|
19 | 19 | import com.intellij.lang.jsgraphql.GraphQLParserDefinition;
|
20 | 20 | import com.intellij.lang.jsgraphql.icons.JSGraphQLIcons;
|
21 | 21 | import com.intellij.lang.jsgraphql.ide.actions.GraphQLEditConfigAction;
|
| 22 | +import com.intellij.lang.jsgraphql.ide.editor.GraphQLIntrospectionService; |
| 23 | +import com.intellij.lang.jsgraphql.ide.notifications.GraphQLNotificationUtil; |
22 | 24 | import com.intellij.lang.jsgraphql.ide.project.graphqlconfig.GraphQLConfigManager;
|
23 | 25 | import com.intellij.lang.jsgraphql.ide.project.graphqlconfig.model.GraphQLConfigEndpoint;
|
24 | 26 | import com.intellij.lang.jsgraphql.ide.project.graphqlconfig.model.GraphQLConfigVariableAwareEndpoint;
|
|
29 | 31 | import com.intellij.lang.jsgraphql.v1.ide.editor.JSGraphQLQueryContextHighlightVisitor;
|
30 | 32 | import com.intellij.lang.jsgraphql.v1.ide.endpoints.JSGraphQLEndpointsModel;
|
31 | 33 | import com.intellij.lang.jsgraphql.v1.ide.project.toolwindow.JSGraphQLLanguageToolWindowManager;
|
32 |
| -import com.intellij.notification.Notification; |
33 | 34 | import com.intellij.notification.NotificationType;
|
34 |
| -import com.intellij.notification.Notifications; |
35 | 35 | import com.intellij.openapi.Disposable;
|
36 | 36 | import com.intellij.openapi.actionSystem.*;
|
37 | 37 | import com.intellij.openapi.application.ApplicationManager;
|
|
51 | 51 | import com.intellij.openapi.ui.ComboBox;
|
52 | 52 | import com.intellij.openapi.util.Disposer;
|
53 | 53 | import com.intellij.openapi.util.Key;
|
| 54 | +import com.intellij.openapi.util.text.StringUtil; |
54 | 55 | import com.intellij.openapi.vcs.CodeSmellDetector;
|
55 | 56 | import com.intellij.openapi.vfs.VirtualFile;
|
56 | 57 | import com.intellij.openapi.vfs.VirtualFileManager;
|
|
68 | 69 | import com.intellij.util.containers.ContainerUtil;
|
69 | 70 | import com.intellij.util.messages.MessageBusConnection;
|
70 | 71 | import com.intellij.util.ui.UIUtil;
|
71 |
| -import org.apache.commons.httpclient.Header; |
72 |
| -import org.apache.commons.httpclient.HttpClient; |
73 |
| -import org.apache.commons.httpclient.methods.PostMethod; |
74 |
| -import org.apache.commons.httpclient.methods.StringRequestEntity; |
75 |
| -import org.apache.commons.httpclient.params.HttpClientParams; |
76 | 72 | import org.apache.commons.lang.StringUtils;
|
77 | 73 | import org.apache.commons.lang.time.StopWatch;
|
| 74 | +import org.apache.http.Header; |
| 75 | +import org.apache.http.HttpRequest; |
| 76 | +import org.apache.http.client.methods.CloseableHttpResponse; |
| 77 | +import org.apache.http.client.methods.HttpPost; |
| 78 | +import org.apache.http.impl.client.CloseableHttpClient; |
| 79 | +import org.apache.http.impl.client.HttpClients; |
| 80 | +import org.apache.http.util.EntityUtils; |
78 | 81 | import org.jetbrains.annotations.NotNull;
|
79 | 82 |
|
80 | 83 | import javax.swing.*;
|
|
83 | 86 | import java.awt.event.MouseAdapter;
|
84 | 87 | import java.awt.event.MouseEvent;
|
85 | 88 | import java.io.IOException;
|
86 |
| -import java.io.UnsupportedEncodingException; |
87 |
| -import java.util.*; |
| 89 | +import java.util.Collection; |
| 90 | +import java.util.HashMap; |
88 | 91 | import java.util.List;
|
| 92 | +import java.util.Map; |
89 | 93 |
|
90 | 94 | /**
|
91 | 95 | * Provides the project-specific GraphQL tool window, including errors view, console, and query result editor.
|
@@ -372,84 +376,85 @@ public void executeGraphQL(Editor editor, VirtualFile virtualFile) {
|
372 | 376 | return;
|
373 | 377 | }
|
374 | 378 | String requestJson = createQueryJsonSerializer().toJson(requestData);
|
375 |
| - final HttpClientParams params = new HttpClientParams(); |
376 |
| - params.setContentCharset("UTF-8"); // set fallback charset to align with JSON spec |
377 |
| - final HttpClient httpClient = new HttpClient(params); |
378 | 379 | final String url = endpoint.getUrl();
|
379 | 380 | try {
|
380 |
| - final PostMethod method = new PostMethod(url); |
381 |
| - setHeadersFromOptions(endpoint, method); |
382 |
| - method.setRequestEntity(new StringRequestEntity(requestJson, "application/json", "UTF-8")); |
383 |
| - |
384 |
| - final Runnable executeQuery = () -> { |
385 |
| - try { |
386 |
| - try { |
387 |
| - editor.putUserData(JS_GRAPH_QL_EDITOR_QUERYING, true); |
388 |
| - StopWatch sw = new StopWatch(); |
389 |
| - sw.start(); |
390 |
| - httpClient.executeMethod(method); |
391 |
| - final String responseJson = Optional.ofNullable(method.getResponseBodyAsString()).orElse(""); |
392 |
| - sw.stop(); |
393 |
| - final Header responseHeader = method.getResponseHeader("Content-Type"); |
394 |
| - final boolean reformatJson = responseHeader != null && responseHeader.getValue() != null && responseHeader.getValue().startsWith("application/json"); |
395 |
| - final Integer errorCount = getErrorCount(responseJson); |
396 |
| - if (fileEditor instanceof TextEditor) { |
397 |
| - final TextEditor textEditor = (TextEditor) fileEditor; |
398 |
| - UIUtil.invokeLaterIfNeeded(() -> { |
399 |
| - updateQueryResultEditor(responseJson, textEditor, reformatJson); |
400 |
| - final StringBuilder queryResultText = new StringBuilder(virtualFile.getName()). |
401 |
| - append(": "). |
402 |
| - append(sw.getTime()). |
403 |
| - append(" ms execution time, "). |
404 |
| - append(bytesToDisplayString(responseJson.length())). |
405 |
| - append(" response"); |
406 |
| - |
407 |
| - if (errorCount != null && errorCount > 0) { |
408 |
| - queryResultText.append(", ").append(errorCount).append(" error").append(errorCount > 1 ? "s" : ""); |
409 |
| - if (context.onError != null) { |
410 |
| - context.onError.run(); |
411 |
| - } |
412 |
| - } |
413 |
| - |
414 |
| - queryResultLabel.setText(queryResultText.toString()); |
415 |
| - queryResultLabel.putClientProperty(FILE_URL_PROPERTY, virtualFile.getUrl()); |
416 |
| - if (!queryResultLabel.isVisible()) { |
417 |
| - queryResultLabel.setVisible(true); |
418 |
| - } |
419 |
| - |
420 |
| - querySuccessLabel.setVisible(errorCount != null); |
421 |
| - if (querySuccessLabel.isVisible()) { |
422 |
| - if (errorCount == 0) { |
423 |
| - querySuccessLabel.setBorder(BorderFactory.createEmptyBorder(2, 8, 0, 0)); |
424 |
| - querySuccessLabel.setIcon(AllIcons.General.InspectionsOK); |
425 |
| - } else { |
426 |
| - querySuccessLabel.setBorder(BorderFactory.createEmptyBorder(2, 12, 0, 4)); |
427 |
| - querySuccessLabel.setIcon(AllIcons.Ide.ErrorPoint); |
428 |
| - } |
429 |
| - } |
430 |
| - showQueryResultEditor(textEditor); |
431 |
| - }); |
432 |
| - } |
433 |
| - } finally { |
434 |
| - editor.putUserData(JS_GRAPH_QL_EDITOR_QUERYING, null); |
435 |
| - } |
436 |
| - } catch (IOException | IllegalArgumentException e) { |
437 |
| - Notifications.Bus.notify(new Notification("GraphQL", "GraphQL Query Error", url + ": " + e.getMessage(), NotificationType.WARNING), myProject); |
438 |
| - } |
439 |
| - }; |
| 381 | + final HttpPost request = GraphQLIntrospectionService.createRequest(endpoint, url, requestJson); |
440 | 382 | final Task.Backgroundable task = new Task.Backgroundable(myProject, "Executing GraphQL", false) {
|
441 | 383 | @Override
|
442 | 384 | public void run(@NotNull ProgressIndicator indicator) {
|
443 | 385 | indicator.setIndeterminate(true);
|
444 |
| - executeQuery.run(); |
| 386 | + runQuery(editor, virtualFile, context, url, request); |
445 | 387 | }
|
446 | 388 | };
|
447 | 389 | ProgressManager.getInstance().run(task);
|
448 |
| - } catch (UnsupportedEncodingException | IllegalStateException | IllegalArgumentException e) { |
449 |
| - Notifications.Bus.notify(new Notification("GraphQL", "GraphQL Query Error", url + ": " + e.getMessage(), NotificationType.ERROR), myProject); |
| 390 | + } catch (IllegalStateException | IllegalArgumentException e) { |
| 391 | + GraphQLNotificationUtil.showGraphQLRequestErrorNotification(myProject, url, e, NotificationType.ERROR, null); |
| 392 | + } |
| 393 | + |
| 394 | + } |
| 395 | + } |
| 396 | + } |
| 397 | + |
| 398 | + private void runQuery(Editor editor, VirtualFile virtualFile, JSGraphQLQueryContext context, String url, HttpPost request) { |
| 399 | + try { |
| 400 | + try (final CloseableHttpClient httpClient = HttpClients.createDefault()) { |
| 401 | + editor.putUserData(JS_GRAPH_QL_EDITOR_QUERYING, true); |
| 402 | + |
| 403 | + String responseJson; |
| 404 | + Header contentType; |
| 405 | + StopWatch sw = new StopWatch(); |
| 406 | + sw.start(); |
| 407 | + try (final CloseableHttpResponse response = httpClient.execute(request)) { |
| 408 | + responseJson = StringUtil.notNullize(EntityUtils.toString(response.getEntity())); |
| 409 | + contentType = response.getFirstHeader("Content-Type"); |
| 410 | + } finally { |
| 411 | + sw.stop(); |
450 | 412 | }
|
451 | 413 |
|
| 414 | + final boolean reformatJson = contentType != null && contentType.getValue() != null && contentType.getValue().startsWith("application/json"); |
| 415 | + final Integer errorCount = getErrorCount(responseJson); |
| 416 | + if (fileEditor instanceof TextEditor) { |
| 417 | + final TextEditor textEditor = (TextEditor) fileEditor; |
| 418 | + UIUtil.invokeLaterIfNeeded(() -> { |
| 419 | + updateQueryResultEditor(responseJson, textEditor, reformatJson); |
| 420 | + final StringBuilder queryResultText = new StringBuilder(virtualFile.getName()). |
| 421 | + append(": "). |
| 422 | + append(sw.getTime()). |
| 423 | + append(" ms execution time, "). |
| 424 | + append(bytesToDisplayString(responseJson.length())). |
| 425 | + append(" response"); |
| 426 | + |
| 427 | + if (errorCount != null && errorCount > 0) { |
| 428 | + queryResultText.append(", ").append(errorCount).append(" error").append(errorCount > 1 ? "s" : ""); |
| 429 | + if (context.onError != null) { |
| 430 | + context.onError.run(); |
| 431 | + } |
| 432 | + } |
| 433 | + |
| 434 | + queryResultLabel.setText(queryResultText.toString()); |
| 435 | + queryResultLabel.putClientProperty(FILE_URL_PROPERTY, virtualFile.getUrl()); |
| 436 | + if (!queryResultLabel.isVisible()) { |
| 437 | + queryResultLabel.setVisible(true); |
| 438 | + } |
| 439 | + |
| 440 | + querySuccessLabel.setVisible(errorCount != null); |
| 441 | + if (querySuccessLabel.isVisible()) { |
| 442 | + if (errorCount == 0) { |
| 443 | + querySuccessLabel.setBorder(BorderFactory.createEmptyBorder(2, 8, 0, 0)); |
| 444 | + querySuccessLabel.setIcon(AllIcons.General.InspectionsOK); |
| 445 | + } else { |
| 446 | + querySuccessLabel.setBorder(BorderFactory.createEmptyBorder(2, 12, 0, 4)); |
| 447 | + querySuccessLabel.setIcon(AllIcons.Ide.ErrorPoint); |
| 448 | + } |
| 449 | + } |
| 450 | + showQueryResultEditor(textEditor); |
| 451 | + }); |
| 452 | + } |
| 453 | + } finally { |
| 454 | + editor.putUserData(JS_GRAPH_QL_EDITOR_QUERYING, null); |
452 | 455 | }
|
| 456 | + } catch (IOException | IllegalArgumentException e) { |
| 457 | + GraphQLNotificationUtil.showGraphQLRequestErrorNotification(myProject, url, e, NotificationType.WARNING, null); |
453 | 458 | }
|
454 | 459 | }
|
455 | 460 |
|
@@ -541,11 +546,11 @@ private static String bytesToDisplayString(long bytes) {
|
541 | 546 | return String.format("%.1f %sb", bytes / Math.pow(1000, exp), pre);
|
542 | 547 | }
|
543 | 548 |
|
544 |
| - public static void setHeadersFromOptions(GraphQLConfigVariableAwareEndpoint endpoint, PostMethod method) { |
| 549 | + public static void setHeadersFromOptions(GraphQLConfigVariableAwareEndpoint endpoint, HttpRequest request) { |
545 | 550 | final Map<String, Object> headers = endpoint.getHeaders();
|
546 | 551 | if (headers != null) {
|
547 | 552 | for (Map.Entry<String, Object> entry : headers.entrySet()) {
|
548 |
| - method.setRequestHeader(entry.getKey(), String.valueOf(entry.getValue())); |
| 553 | + request.setHeader(entry.getKey(), String.valueOf(entry.getValue())); |
549 | 554 | }
|
550 | 555 | }
|
551 | 556 | }
|
|
0 commit comments