1
+ package org.androidstudio.plugin.util
2
+
3
+ import com.android.tools.idea.gradle.AndroidGradleJavaProjectModelModifier
4
+ import com.android.tools.idea.gradle.dsl.api.GradleBuildModel
5
+ import com.android.tools.idea.gradle.dsl.api.dependencies.ArtifactDependencySpec
6
+ import com.android.tools.idea.gradle.dsl.api.dependencies.CommonConfigurationNames
7
+ import com.android.tools.idea.gradle.project.sync.GradleSyncInvoker
8
+ import com.android.tools.idea.gradle.project.sync.GradleSyncListener
9
+ import com.android.tools.idea.gradle.project.sync.idea.GradleSyncExecutor
10
+ import com.android.tools.idea.gradle.util.GradleUtil
11
+ import com.android.tools.idea.project.AndroidProjectInfo
12
+ import com.android.tools.idea.projectsystem.TestArtifactSearchScopes
13
+ import com.google.wireless.android.sdk.stats.GradleSyncStats
14
+ import com.intellij.openapi.command.WriteCommandAction
15
+ import com.intellij.openapi.command.undo.BasicUndoableAction
16
+ import com.intellij.openapi.command.undo.UndoManager
17
+ import com.intellij.openapi.externalSystem.ExternalSystemModulePropertyManager
18
+ import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx
19
+ import com.intellij.openapi.module.Module
20
+ import com.intellij.openapi.project.Project
21
+ import com.intellij.openapi.roots.DependencyScope
22
+ import com.intellij.openapi.roots.ExternalLibraryDescriptor
23
+ import com.intellij.openapi.vfs.VirtualFile
24
+ import com.intellij.util.containers.ContainerUtil
25
+ import org.jetbrains.concurrency.AsyncPromise
26
+ import org.jetbrains.concurrency.Promise
27
+
28
+ class UtAndroidGradleJavaProjectModelModifier : AndroidGradleJavaProjectModelModifier () {
29
+ override fun addExternalLibraryDependency (
30
+ modules : Collection <Module ?>,
31
+ descriptor : ExternalLibraryDescriptor ,
32
+ scope : DependencyScope
33
+ ): Promise <Void ?>? {
34
+ val module = ContainerUtil .getFirstItem(modules) ? : return null
35
+
36
+ if (! isAndroidGradleProject(module.project)) {
37
+ return null
38
+ }
39
+
40
+ val dependencySpec = ArtifactDependencySpec .create(descriptor.libraryArtifactId, descriptor.libraryGroupId, descriptor.preferredVersion)
41
+ return addExternalLibraryDependency(module, dependencySpec, scope)
42
+
43
+ }
44
+
45
+ private fun addExternalLibraryDependency (
46
+ module : Module ,
47
+ dependencySpec : ArtifactDependencySpec ,
48
+ scope : DependencyScope ,
49
+ ): Promise <Void ?>? {
50
+ val project = module.project
51
+ val openedFile = FileEditorManagerEx .getInstanceEx(project).currentFile
52
+ val buildModelsToUpdate: MutableList <GradleBuildModel > = ArrayList ()
53
+
54
+ val buildModel = GradleBuildModel .get(module) ? : return null
55
+ val configurationName = getConfigurationName(module, scope, openedFile)
56
+ val dependencies = buildModel.dependencies()
57
+ dependencies.addArtifact(configurationName, dependencySpec)
58
+ buildModelsToUpdate.add(buildModel)
59
+
60
+ WriteCommandAction .writeCommandAction(project).withName(" Add Gradle Library Dependency" ).run<RuntimeException > {
61
+ buildModelsToUpdate.forEach { buildModel -> buildModel.applyChanges() }
62
+ registerUndoAction(project)
63
+ }
64
+
65
+ return doAndroidGradleSync(project, GradleSyncStats .Trigger .TRIGGER_MODIFIER_ADD_LIBRARY_DEPENDENCY )
66
+ }
67
+
68
+ private fun getConfigurationName (module : Module , scope : DependencyScope , openedFile : VirtualFile ? ): String =
69
+ GradleUtil .mapConfigurationName(
70
+ getLegacyConfigurationName(module, scope, openedFile),
71
+ GradleUtil .getAndroidGradleModelVersionInUse(module),
72
+ false
73
+ )
74
+
75
+ private fun getLegacyConfigurationName (
76
+ module : Module ,
77
+ scope : DependencyScope ,
78
+ openedFile : VirtualFile ?
79
+ ): String {
80
+ if (! scope.isForProductionCompile) {
81
+ val testScopes = TestArtifactSearchScopes .getInstance(module)
82
+ if (testScopes != null && openedFile != null ) {
83
+ return if (testScopes.isAndroidTestSource(openedFile)) CommonConfigurationNames .ANDROID_TEST_COMPILE else CommonConfigurationNames .TEST_COMPILE
84
+ }
85
+ }
86
+ return CommonConfigurationNames .COMPILE
87
+ }
88
+
89
+ private fun registerUndoAction (project : Project ) {
90
+ UndoManager .getInstance(project).undoableActionPerformed(object : BasicUndoableAction () {
91
+
92
+ override fun undo () {
93
+ doAndroidGradleSync(project, GradleSyncStats .Trigger .TRIGGER_MODIFIER_ACTION_UNDONE )
94
+
95
+ }
96
+
97
+ override fun redo () {
98
+ doAndroidGradleSync(project, GradleSyncStats .Trigger .TRIGGER_MODIFIER_ACTION_REDONE )
99
+ }
100
+ })
101
+ }
102
+
103
+ private fun isAndroidGradleProject (project : Project ): Boolean = AndroidProjectInfo .getInstance(project).requiresAndroidModel()
104
+
105
+ private fun doAndroidGradleSync (project : Project , trigger : GradleSyncStats .Trigger ): AsyncPromise <Void ?> {
106
+ val promise = AsyncPromise <Void ?>()
107
+ val request = GradleSyncInvoker .Request (trigger)
108
+ val listener = object : GradleSyncListener {
109
+ override fun syncSucceeded (project : Project ) {
110
+ promise.setResult(null )
111
+ }
112
+
113
+ override fun syncFailed (project : Project , errorMessage : String ) {
114
+ promise.setError(errorMessage)
115
+ }
116
+ }
117
+ GradleSyncExecutor (project).sync(request, listener)
118
+
119
+ return promise
120
+ }
121
+ }
0 commit comments