|
11 | 11 | import com.google.gson.Gson; |
12 | 12 | import com.google.gson.JsonSyntaxException; |
13 | 13 | import com.intellij.ide.actions.CreateFileAction; |
14 | | -import com.intellij.ide.impl.DataManagerImpl; |
15 | 14 | import com.intellij.ide.util.PropertiesComponent; |
16 | 15 | import com.intellij.lang.jsgraphql.GraphQLBundle; |
17 | 16 | import com.intellij.lang.jsgraphql.GraphQLSettings; |
|
26 | 25 | import com.intellij.notification.NotificationType; |
27 | 26 | import com.intellij.notification.Notifications; |
28 | 27 | import com.intellij.openapi.Disposable; |
29 | | -import com.intellij.openapi.actionSystem.ActionManager; |
30 | | -import com.intellij.openapi.actionSystem.ActionPlaces; |
31 | 28 | import com.intellij.openapi.actionSystem.AnAction; |
32 | 29 | import com.intellij.openapi.actionSystem.AnActionEvent; |
33 | 30 | import com.intellij.openapi.application.ApplicationManager; |
34 | 31 | import com.intellij.openapi.application.WriteAction; |
| 32 | +import com.intellij.openapi.command.WriteCommandAction; |
35 | 33 | import com.intellij.openapi.components.ServiceManager; |
36 | | -import com.intellij.openapi.editor.Editor; |
37 | 34 | import com.intellij.openapi.editor.EditorBundle; |
38 | 35 | import com.intellij.openapi.fileEditor.FileEditor; |
39 | 36 | import com.intellij.openapi.fileEditor.FileEditorManager; |
|
49 | 46 | import com.intellij.openapi.util.text.StringUtil; |
50 | 47 | import com.intellij.openapi.vfs.VirtualFile; |
51 | 48 | import com.intellij.psi.PsiDirectory; |
| 49 | +import com.intellij.psi.PsiDocumentManager; |
52 | 50 | import com.intellij.psi.PsiFile; |
53 | 51 | import com.intellij.psi.PsiFileFactory; |
| 52 | +import com.intellij.psi.codeStyle.CodeStyleManager; |
54 | 53 | import com.intellij.psi.impl.file.PsiDirectoryFactory; |
55 | 54 | import com.intellij.util.Consumer; |
56 | 55 | import com.intellij.util.ExceptionUtil; |
@@ -245,45 +244,51 @@ public String printIntrospectionAsGraphQL(@NotNull Map<String, Object> introspec |
245 | 244 | @SuppressWarnings("unchecked") |
246 | 245 | @NotNull |
247 | 246 | private Map<String, Object> getIntrospectionSchemaData(@NotNull Map<String, Object> introspection) { |
248 | | - if (!introspection.containsKey("__schema")) { |
249 | | - // possibly a full query result |
250 | | - if (introspection.containsKey("errors")) { |
251 | | - final Object errorsValue = introspection.get("errors"); |
252 | | - if (errorsValue instanceof List && ((List<?>) errorsValue).size() == 0) { |
253 | | - if (!PropertiesComponent.getInstance().isTrueValue(DISABLE_EMPTY_ERRORS_WARNING_KEY)) { |
254 | | - final Notification emptyErrorNotification = new Notification( |
255 | | - GraphQLNotificationUtil.NOTIFICATION_GROUP_ID, |
256 | | - GraphQLBundle.message("graphql.notification.introspection.error.title"), |
257 | | - GraphQLBundle.message("graphql.notification.introspection.empty.errors"), |
258 | | - NotificationType.WARNING |
259 | | - ); |
260 | | - |
261 | | - final AnAction dontShowAgainAction = new NotificationAction(EditorBundle.message("notification.dont.show.again.message")) { |
262 | | - @Override |
263 | | - public void actionPerformed(@NotNull AnActionEvent e, @NotNull Notification notification) { |
264 | | - PropertiesComponent.getInstance().setValue(DISABLE_EMPTY_ERRORS_WARNING_KEY, "true"); |
265 | | - notification.hideBalloon(); |
266 | | - } |
267 | | - }; |
268 | | - |
269 | | - emptyErrorNotification.addAction(dontShowAgainAction); |
270 | | - Notifications.Bus.notify(emptyErrorNotification, myProject); |
271 | | - } |
272 | | - } else { |
273 | | - throw new IllegalArgumentException(GraphQLBundle.message("graphql.introspection.errors", new Gson().toJson(introspection.get("errors")))); |
274 | | - } |
275 | | - } |
276 | | - if (!introspection.containsKey("data")) { |
277 | | - throw new IllegalArgumentException(GraphQLBundle.message("graphql.introspection.missing.data")); |
278 | | - } |
279 | | - introspection = (Map<String, Object>) introspection.get("data"); |
280 | | - if (!introspection.containsKey("__schema")) { |
281 | | - throw new IllegalArgumentException(GraphQLBundle.message("graphql.introspection.missing.schema")); |
| 247 | + if (introspection.containsKey("__schema")) { |
| 248 | + return introspection; |
| 249 | + } |
| 250 | + |
| 251 | + // possibly a full query result |
| 252 | + if (introspection.containsKey("errors")) { |
| 253 | + final Object errorsValue = introspection.get("errors"); |
| 254 | + if (errorsValue instanceof List && ((List<?>) errorsValue).size() == 0) { |
| 255 | + showEmptyErrorsNotification(); |
| 256 | + } else { |
| 257 | + throw new IllegalArgumentException(GraphQLBundle.message("graphql.introspection.errors", new Gson().toJson(introspection.get("errors")))); |
282 | 258 | } |
283 | 259 | } |
| 260 | + if (!introspection.containsKey("data")) { |
| 261 | + throw new IllegalArgumentException(GraphQLBundle.message("graphql.introspection.missing.data")); |
| 262 | + } |
| 263 | + introspection = (Map<String, Object>) introspection.get("data"); |
| 264 | + if (!introspection.containsKey("__schema")) { |
| 265 | + throw new IllegalArgumentException(GraphQLBundle.message("graphql.introspection.missing.schema")); |
| 266 | + } |
284 | 267 | return introspection; |
285 | 268 | } |
286 | 269 |
|
| 270 | + private void showEmptyErrorsNotification() { |
| 271 | + if (!PropertiesComponent.getInstance().isTrueValue(DISABLE_EMPTY_ERRORS_WARNING_KEY)) { |
| 272 | + final Notification emptyErrorNotification = new Notification( |
| 273 | + GraphQLNotificationUtil.NOTIFICATION_GROUP_ID, |
| 274 | + GraphQLBundle.message("graphql.notification.introspection.error.title"), |
| 275 | + GraphQLBundle.message("graphql.notification.introspection.empty.errors"), |
| 276 | + NotificationType.WARNING |
| 277 | + ); |
| 278 | + |
| 279 | + final AnAction dontShowAgainAction = new NotificationAction(EditorBundle.message("notification.dont.show.again.message")) { |
| 280 | + @Override |
| 281 | + public void actionPerformed(@NotNull AnActionEvent e, @NotNull Notification notification) { |
| 282 | + PropertiesComponent.getInstance().setValue(DISABLE_EMPTY_ERRORS_WARNING_KEY, "true"); |
| 283 | + notification.hideBalloon(); |
| 284 | + } |
| 285 | + }; |
| 286 | + |
| 287 | + emptyErrorNotification.addAction(dontShowAgainAction); |
| 288 | + Notifications.Bus.notify(emptyErrorNotification, myProject); |
| 289 | + } |
| 290 | + } |
| 291 | + |
287 | 292 | private GraphQLSchema buildIntrospectionSchema(TypeDefinitionRegistry registry) { |
288 | 293 | final RuntimeWiring runtimeWiring = EchoingWiringFactory.newEchoingWiring(wiring -> { |
289 | 294 | Map<String, ScalarTypeDefinition> scalars = registry.scalars(); |
@@ -340,64 +345,72 @@ void createOrUpdateIntrospectionOutputFile(@NotNull String schemaText, |
340 | 345 | @NotNull IntrospectionOutputFormat format, |
341 | 346 | @NotNull VirtualFile introspectionSourceFile, |
342 | 347 | @NotNull String outputFileName) { |
343 | | - WriteAction.run(() -> { |
344 | | - try { |
345 | | - final String header; |
346 | | - switch (format) { |
347 | | - case SDL: |
348 | | - header = "# This file was generated based on \"" + introspectionSourceFile.getName() + "\". Do not edit manually.\n\n"; |
349 | | - break; |
350 | | - case JSON: |
351 | | - header = ""; |
352 | | - break; |
353 | | - default: |
354 | | - throw new IllegalArgumentException("unsupported output format: " + format); |
355 | | - } |
356 | | - String relativeOutputFileName = FileUtil.toSystemIndependentName(outputFileName); |
357 | | - VirtualFile outputFile = introspectionSourceFile.getParent().findFileByRelativePath(relativeOutputFileName); |
358 | | - if (outputFile == null) { |
359 | | - PsiDirectory directory = PsiDirectoryFactory.getInstance(myProject).createDirectory(introspectionSourceFile.getParent()); |
360 | | - CreateFileAction.MkDirs dirs = new CreateFileAction.MkDirs(relativeOutputFileName, directory); |
361 | | - outputFile = dirs.directory.getVirtualFile().createChildData(introspectionSourceFile, dirs.newName); |
362 | | - } |
363 | | - outputFile.putUserData(GraphQLSchemaKeys.IS_GRAPHQL_INTROSPECTION_JSON, true); |
364 | | - final FileEditor[] fileEditors = FileEditorManager.getInstance(myProject).openFile(outputFile, true, true); |
365 | | - if (fileEditors.length > 0) { |
366 | | - final FileEditor fileEditor = fileEditors[0]; |
367 | | - setEditorTextAndFormatLines(header + schemaText, fileEditor); |
368 | | - } else { |
369 | | - Notifications.Bus.notify(new Notification(GraphQLNotificationUtil.NOTIFICATION_GROUP_ID, GraphQLBundle.message("graphql.notification.error.title"), |
370 | | - GraphQLBundle.message("graphql.notification.unable.to.open.editor", outputFile.getPath()), NotificationType.ERROR)); |
371 | | - } |
372 | | - } catch (IOException ioe) { |
373 | | - Notifications.Bus.notify(new Notification( |
374 | | - GraphQLNotificationUtil.NOTIFICATION_GROUP_ID, |
375 | | - GraphQLBundle.message("graphql.notification.error.title"), |
376 | | - GraphQLBundle.message("graphql.notification.unable.to.create.file", |
377 | | - outputFileName, introspectionSourceFile.getParent().getPath(), GraphQLNotificationUtil.formatExceptionMessage(ioe)), |
378 | | - NotificationType.ERROR |
379 | | - )); |
| 348 | + try { |
| 349 | + final String header; |
| 350 | + switch (format) { |
| 351 | + case SDL: |
| 352 | + header = "# This file was generated based on \"" + introspectionSourceFile.getName() + "\". Do not edit manually.\n\n"; |
| 353 | + break; |
| 354 | + case JSON: |
| 355 | + header = ""; |
| 356 | + break; |
| 357 | + default: |
| 358 | + throw new IllegalArgumentException("unsupported output format: " + format); |
380 | 359 | } |
381 | | - }); |
382 | | - } |
383 | 360 |
|
384 | | - private void setEditorTextAndFormatLines(String text, FileEditor fileEditor) { |
385 | | - if (fileEditor instanceof TextEditor) { |
386 | | - // IntelliJ only allows the \n linebreak inside editor documents. |
387 | | - final String normalizedText = StringUtil.convertLineSeparators(text); |
388 | | - final Editor editor = ((TextEditor) fileEditor).getEditor(); |
389 | | - editor.getDocument().setText(normalizedText); |
390 | | - AnAction reformatCode = ActionManager.getInstance().getAction("ReformatCode"); |
391 | | - if (reformatCode != null) { |
392 | | - final AnActionEvent actionEvent = AnActionEvent.createFromDataContext( |
393 | | - ActionPlaces.UNKNOWN, |
394 | | - null, |
395 | | - new DataManagerImpl.MyDataContext(editor.getComponent()) |
396 | | - ); |
397 | | - reformatCode.actionPerformed(actionEvent); |
| 361 | + VirtualFile outputFile = createSchemaFile(introspectionSourceFile, FileUtil.toSystemIndependentName(outputFileName)); |
| 362 | + |
| 363 | + final FileEditor[] fileEditors = FileEditorManager.getInstance(myProject).openFile(outputFile, true, true); |
| 364 | + if (fileEditors.length == 0) { |
| 365 | + showUnableToOpenEditorNotification(outputFile); |
| 366 | + return; |
398 | 367 | } |
399 | 368 |
|
| 369 | + TextEditor textEditor = ObjectUtils.tryCast(fileEditors[0], TextEditor.class); |
| 370 | + if (textEditor == null) { |
| 371 | + showUnableToOpenEditorNotification(outputFile); |
| 372 | + return; |
| 373 | + } |
| 374 | + |
| 375 | + WriteCommandAction.runWriteCommandAction(myProject, () -> { |
| 376 | + com.intellij.openapi.editor.Document document = textEditor.getEditor().getDocument(); |
| 377 | + document.setText(StringUtil.convertLineSeparators(header + schemaText)); |
| 378 | + PsiDocumentManager.getInstance(myProject).commitDocument(document); |
| 379 | + |
| 380 | + PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(document); |
| 381 | + if (psiFile != null) { |
| 382 | + CodeStyleManager.getInstance(myProject).reformat(psiFile); |
| 383 | + } |
| 384 | + }); |
| 385 | + } catch (IOException ioe) { |
| 386 | + Notifications.Bus.notify(new Notification( |
| 387 | + GraphQLNotificationUtil.NOTIFICATION_GROUP_ID, |
| 388 | + GraphQLBundle.message("graphql.notification.error.title"), |
| 389 | + GraphQLBundle.message("graphql.notification.unable.to.create.file", |
| 390 | + outputFileName, introspectionSourceFile.getParent().getPath(), GraphQLNotificationUtil.formatExceptionMessage(ioe)), |
| 391 | + NotificationType.ERROR |
| 392 | + )); |
| 393 | + } |
| 394 | + } |
| 395 | + |
| 396 | + private void showUnableToOpenEditorNotification(@NotNull VirtualFile outputFile) { |
| 397 | + Notifications.Bus.notify(new Notification(GraphQLNotificationUtil.NOTIFICATION_GROUP_ID, GraphQLBundle.message("graphql.notification.error.title"), |
| 398 | + GraphQLBundle.message("graphql.notification.unable.to.open.editor", outputFile.getPath()), NotificationType.ERROR)); |
| 399 | + } |
| 400 | + |
| 401 | + @NotNull |
| 402 | + private VirtualFile createSchemaFile(@NotNull VirtualFile introspectionSourceFile, |
| 403 | + @NotNull String relativeOutputFileName) throws IOException { |
| 404 | + VirtualFile outputFile = introspectionSourceFile.getParent().findFileByRelativePath(relativeOutputFileName); |
| 405 | + if (outputFile == null) { |
| 406 | + outputFile = WriteAction.compute(() -> { |
| 407 | + PsiDirectory directory = PsiDirectoryFactory.getInstance(myProject).createDirectory(introspectionSourceFile.getParent()); |
| 408 | + CreateFileAction.MkDirs dirs = new CreateFileAction.MkDirs(relativeOutputFileName, directory); |
| 409 | + return dirs.directory.getVirtualFile().createChildData(introspectionSourceFile, dirs.newName); |
| 410 | + }); |
400 | 411 | } |
| 412 | + outputFile.putUserData(GraphQLSchemaKeys.IS_GRAPHQL_INTROSPECTION_JSON, true); |
| 413 | + return outputFile; |
401 | 414 | } |
402 | 415 |
|
403 | 416 | @Override |
|
0 commit comments