Add new modules to IDE layout
[idea/community.git] / platform / build-scripts / groovy / org / jetbrains / intellij / build / impl / PlatformModules.groovy
1 // Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
2 package org.jetbrains.intellij.build.impl
3
4 import groovy.transform.CompileDynamic
5 import groovy.transform.CompileStatic
6 import org.jetbrains.annotations.NotNull
7 import org.jetbrains.annotations.Nullable
8 import org.jetbrains.intellij.build.BuildContext
9 import org.jetbrains.intellij.build.ProductModulesLayout
10 import org.jetbrains.jps.model.library.JpsLibrary
11 import org.w3c.dom.Element
12 import org.w3c.dom.NodeList
13
14 import javax.xml.parsers.DocumentBuilderFactory
15 import java.nio.file.Files
16 import java.nio.file.Path
17
18 import static org.jetbrains.intellij.build.impl.BaseLayout.PLATFORM_JAR
19
20 @CompileStatic
21 final class PlatformModules {
22   /**
23    * List of modules which are included into lib/platform-api.jar in all IntelliJ based IDEs.
24    */
25   static List<String> PLATFORM_API_MODULES = List.of(
26     "intellij.platform.analysis",
27     "intellij.platform.builtInServer",
28     "intellij.platform.core",
29     "intellij.platform.diff",
30     "intellij.platform.vcs.dvcs",
31     "intellij.platform.editor",
32     "intellij.platform.externalSystem",
33     "intellij.platform.codeStyle",
34     "intellij.platform.indexing",
35     "intellij.platform.jps.model",
36     "intellij.platform.lang",
37     "intellij.platform.lang.core",
38     "intellij.platform.lvcs",
39     "intellij.platform.ide",
40     "intellij.platform.projectModel",
41     "intellij.platform.remote.core",
42     "intellij.platform.remoteServers.agent.rt",
43     "intellij.platform.remoteServers",
44     "intellij.platform.tasks",
45     "intellij.platform.usageView",
46     "intellij.platform.vcs.core",
47     "intellij.platform.vcs",
48     "intellij.platform.vcs.log",
49     "intellij.platform.vcs.log.graph",
50     "intellij.platform.execution",
51     "intellij.platform.debugger",
52     "intellij.xml.analysis",
53     "intellij.xml",
54     "intellij.xml.psi",
55     "intellij.xml.structureView",
56     "intellij.platform.concurrency",
57   )
58
59   /**
60    * List of modules which are included into lib/platform-impl.jar in all IntelliJ based IDEs.
61    */
62   static List<String> PLATFORM_IMPLEMENTATION_MODULES = List.of(
63     "intellij.platform.analysis.impl",
64     "intellij.platform.builtInServer.impl",
65     "intellij.platform.core.impl",
66     "intellij.platform.diff.impl",
67     "intellij.platform.editor.ex",
68     "intellij.platform.codeStyle.impl",
69     "intellij.platform.indexing.impl",
70     "intellij.platform.elevation",
71     "intellij.platform.elevation.client",
72     "intellij.platform.elevation.common",
73     "intellij.platform.elevation.daemon",
74     "intellij.platform.execution.impl",
75     "intellij.platform.inspect",
76     "intellij.platform.lang.impl",
77     "intellij.platform.workspaceModel.storage",
78     "intellij.platform.workspaceModel.jps",
79     "intellij.platform.lvcs.impl",
80     "intellij.platform.ide.impl",
81     "intellij.platform.ide.core.impl",
82     "intellij.platform.vfs.impl",
83     "intellij.platform.projectModel.impl",
84     "intellij.platform.externalSystem.impl",
85     "intellij.platform.scriptDebugger.protocolReaderRuntime",
86     "intellij.regexp",
87     "intellij.platform.macro",
88     "intellij.platform.remoteServers.impl",
89     "intellij.platform.scriptDebugger.backend",
90     "intellij.platform.scriptDebugger.ui",
91     "intellij.platform.smRunner",
92     "intellij.platform.smRunner.vcs",
93     "intellij.platform.structureView.impl",
94     "intellij.platform.tasks.impl",
95     "intellij.platform.testRunner",
96     "intellij.platform.debugger.impl",
97     "intellij.platform.configurationStore.impl",
98     "intellij.platform.serviceContainer",
99     "intellij.platform.objectSerializer",
100     "intellij.platform.diagnostic",
101     "intellij.platform.core.ui",
102     "intellij.platform.credentialStore",
103     "intellij.platform.rd.community",
104     "intellij.platform.ml.impl"
105   )
106
107   private static final String UTIL_JAR = "util.jar"
108
109   @CompileDynamic
110   static PlatformLayout createPlatformLayout(ProductModulesLayout productLayout,
111                                              Set<String> allProductDependencies,
112                                              List<JpsLibrary> additionalProjectLevelLibraries,
113                                              BuildContext buildContext) {
114     PlatformLayout.platform(productLayout.platformLayoutCustomizer) {
115       BaseLayoutSpec.metaClass.addModule = { String moduleName ->
116         if (!productLayout.excludedModuleNames.contains(moduleName)) {
117           withModule(moduleName)
118         }
119       }
120       BaseLayoutSpec.metaClass.addModule = { String moduleName, String relativeJarPath ->
121         if (!productLayout.excludedModuleNames.contains(moduleName)) {
122           withModule(moduleName, relativeJarPath)
123         }
124       }
125
126       productLayout.additionalPlatformJars.entrySet().each {
127         String jarName = it.key
128         it.value.each {
129           addModule(it, jarName)
130         }
131       }
132
133       for (String module in PLATFORM_API_MODULES) {
134         addModule(module, "platform-api.jar")
135       }
136       for (String module in PLATFORM_IMPLEMENTATION_MODULES) {
137         addModule(module, PLATFORM_JAR)
138       }
139       for (String module in productLayout.productApiModules) {
140         addModule(module, "openapi.jar")
141       }
142
143       for (String module in productLayout.productImplementationModules) {
144         boolean isRelocated = module == "intellij.xml.dom.impl" ||
145                               module == "intellij.platform.structuralSearch" ||
146                               module == "intellij.platform.duplicates.analysis"
147         addModule(module, isRelocated ? PLATFORM_JAR : productLayout.mainJarName)
148       }
149
150       productLayout.moduleExcludes.entrySet().each {
151         layout.moduleExcludes.putValues(it.key, it.value)
152       }
153
154       addModule("intellij.platform.util", UTIL_JAR)
155       addModule("intellij.platform.util.rt", UTIL_JAR)
156       addModule("intellij.platform.util.zip", UTIL_JAR)
157       addModule("intellij.platform.util.classLoader", UTIL_JAR)
158       addModule("intellij.platform.util.text.matching", UTIL_JAR)
159       addModule("intellij.platform.util.collections", UTIL_JAR)
160       addModule("intellij.platform.util.strings", UTIL_JAR)
161       addModule("intellij.platform.util.xmlDom", UTIL_JAR)
162       addModule("intellij.platform.util.diagnostic", UTIL_JAR)
163       addModule("intellij.platform.util.ui", UTIL_JAR)
164       addModule("intellij.platform.util.ex", UTIL_JAR)
165       addModule("intellij.platform.ide.util.io", UTIL_JAR)
166       addModule("intellij.platform.extensions", UTIL_JAR)
167
168       withoutModuleLibrary("intellij.platform.credentialStore", "dbus-java")
169       addModule("intellij.platform.statistics", "stats.jar")
170       addModule("intellij.platform.statistics.uploader", "stats.jar")
171       addModule("intellij.platform.statistics.config", "stats.jar")
172       addModule("intellij.platform.statistics.devkit")
173
174       for (String module in List.of("intellij.relaxng",
175                                     "intellij.json",
176                                     "intellij.spellchecker",
177                                     "intellij.xml.analysis.impl",
178                                     "intellij.xml.psi.impl",
179                                     "intellij.xml.structureView.impl",
180                                     "intellij.xml.impl")) {
181         addModule(module, PLATFORM_JAR)
182       }
183
184       addModule("intellij.platform.vcs.impl", PLATFORM_JAR)
185       addModule("intellij.platform.vcs.dvcs.impl", PLATFORM_JAR)
186       addModule("intellij.platform.vcs.log.graph.impl", PLATFORM_JAR)
187       addModule("intellij.platform.vcs.log.impl", PLATFORM_JAR)
188       addModule("intellij.platform.collaborationTools", PLATFORM_JAR)
189
190       addModule("intellij.platform.objectSerializer.annotations")
191
192       addModule("intellij.platform.bootstrap")
193       addModule("intellij.java.guiForms.rt")
194       addModule("intellij.platform.boot", "bootstrap.jar")
195
196       addModule("intellij.platform.icons", PLATFORM_JAR)
197       addModule("intellij.platform.resources", PLATFORM_JAR)
198       addModule("intellij.platform.colorSchemes", PLATFORM_JAR)
199       addModule("intellij.platform.resources.en", PLATFORM_JAR)
200
201       addModule("intellij.platform.jps.model.serialization", "jps-model.jar")
202       addModule("intellij.platform.jps.model.impl", "jps-model.jar")
203
204       addModule("intellij.platform.externalSystem.rt", "external-system-rt.jar")
205
206       addModule("intellij.platform.cdsAgent", "cds/classesLogAgent.jar")
207
208       if (allProductDependencies.contains("intellij.platform.coverage")) {
209         addModule("intellij.platform.coverage")
210       }
211
212       for (String libraryName in productLayout.projectLibrariesToUnpackIntoMainJar) {
213         withProjectLibraryUnpackedIntoJar(libraryName, productLayout.mainJarName)
214       }
215
216       String productPluginSourceModuleName = buildContext.productProperties.applicationInfoModule
217       if (productPluginSourceModuleName != null) {
218         List<String> modules = getProductPluginContentModules(buildContext, productPluginSourceModuleName)
219         if (modules != null) {
220           for (String name : modules) {
221             withModule(name, PLATFORM_JAR)
222           }
223         }
224       }
225
226       layout.projectLibrariesToUnpack.putValues(UTIL_JAR, List.of(
227         "JDOM",
228         "ASM",
229         "Trove4j",
230         "aalto-xml",
231         "netty-buffer",
232         "netty-codec-http",
233         "netty-handler-proxy",
234         "Log4J",
235         "fastutil-min",
236       ))
237
238       for (JpsLibrary library in additionalProjectLevelLibraries) {
239         if (!productLayout.projectLibrariesToUnpackIntoMainJar.contains(library.name) &&
240             !layout.projectLibrariesToUnpack.values().contains(library.name) &&
241             !layout.excludedProjectLibraries.contains(library.name)) {
242           withProjectLibrary(library.name)
243         }
244       }
245
246       withProjectLibrariesFromIncludedModules(buildContext)
247
248       for (String toRemoveVersion : List.of("jna", "jetbrains-annotations-java5")) {
249         removeVersionFromProjectLibraryJarNames(toRemoveVersion)
250       }
251     }
252   }
253
254   private static @Nullable List<String> getProductPluginContentModules(@NotNull BuildContext buildContext,
255                                                                        @NotNull String productPluginSourceModuleName) {
256     Path file = buildContext.findFileInModuleSources(productPluginSourceModuleName, "META-INF/plugin.xml")
257     if (file == null) {
258       file = buildContext.findFileInModuleSources(productPluginSourceModuleName,
259                                                   "META-INF/" + buildContext.productProperties.platformPrefix + "Plugin.xml")
260       if (file == null) {
261         buildContext.messages.warning("Cannot find product plugin descriptor in '$productPluginSourceModuleName' module")
262         return null
263       }
264     }
265
266     Files.newInputStream(file).withCloseable {
267       NodeList contentList = DocumentBuilderFactory.newDefaultInstance().newDocumentBuilder()
268         .parse(it, file.toString()).getDocumentElement().getElementsByTagName("content")
269       if (contentList.length != 0) {
270         NodeList modules = ((Element)contentList.item(0)).getElementsByTagName("module")
271         List<String> result = new ArrayList<>(modules.length)
272         for (int i = 0; i < modules.length; i++) {
273           Element module = (Element)modules.item(i)
274           result.add(module.getAttribute("name"))
275         }
276         return result
277       }
278       return null
279     }
280   }
281 }