2 * Copyright 2000-2014 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 org.jetbrains.plugins.gradle.tooling.builder;
18 import org.gradle.api.Project;
19 import org.gradle.api.Task;
20 import org.gradle.api.tasks.SourceSet;
21 import org.gradle.api.tasks.SourceSetContainer;
22 import org.gradle.api.tasks.SourceSetOutput;
23 import org.gradle.api.tasks.bundling.Jar;
24 import org.gradle.api.tasks.testing.Test;
25 import org.gradle.plugins.ide.idea.IdeaPlugin;
26 import org.gradle.plugins.ide.idea.model.IdeaModel;
27 import org.gradle.util.GradleVersion;
28 import org.jetbrains.annotations.NotNull;
29 import org.jetbrains.annotations.Nullable;
30 import org.jetbrains.plugins.gradle.model.ExtIdeaContentRoot;
31 import org.jetbrains.plugins.gradle.model.ModuleExtendedModel;
32 import org.jetbrains.plugins.gradle.tooling.ErrorMessageBuilder;
33 import org.jetbrains.plugins.gradle.tooling.ModelBuilderService;
34 import org.jetbrains.plugins.gradle.tooling.internal.IdeaCompilerOutputImpl;
35 import org.jetbrains.plugins.gradle.tooling.internal.IdeaContentRootImpl;
36 import org.jetbrains.plugins.gradle.tooling.internal.IdeaSourceDirectoryImpl;
37 import org.jetbrains.plugins.gradle.tooling.internal.ModuleExtendedModelImpl;
40 import java.io.IOException;
44 * @author Vladislav.Soroka
47 public class ModuleExtendedModelBuilderImpl implements ModelBuilderService {
49 private static final String SOURCE_SETS_PROPERTY = "sourceSets";
50 private static final String TEST_SRC_DIRS_PROPERTY = "testSrcDirs";
53 public boolean canBuild(String modelName) {
54 return ModuleExtendedModel.class.getName().equals(modelName);
59 public Object buildAll(String modelName, Project project) {
61 final String moduleName = project.getName();
62 final String moduleGroup = project.getGroup().toString();
63 final String moduleVersion = project.getVersion().toString();
64 final File buildDir = project.getBuildDir();
66 final ModuleExtendedModelImpl moduleVersionModel = new ModuleExtendedModelImpl(moduleName, moduleGroup, moduleVersion, buildDir);
68 final List<File> artifacts = new ArrayList<File>();
69 for (Task task : project.getTasks()) {
70 if (task instanceof Jar) {
72 artifacts.add(jar.getArchivePath());
76 moduleVersionModel.setArtifacts(artifacts);
78 final Set<String> sourceDirectories = new HashSet<String>();
79 final Set<String> testDirectories = new HashSet<String>();
80 final Set<String> resourceDirectories = new HashSet<String>();
81 final Set<String> testResourceDirectories = new HashSet<String>();
83 final List<File> testClassesDirs = new ArrayList<File>();
84 for (Task task : project.getTasks()) {
85 if (task instanceof Test) {
86 Test test = (Test)task;
87 testClassesDirs.add(test.getTestClassesDir());
89 if (test.hasProperty(TEST_SRC_DIRS_PROPERTY)) {
90 Object testSrcDirs = test.property(TEST_SRC_DIRS_PROPERTY);
91 if (testSrcDirs instanceof Iterable) {
92 for (Object dir : Iterable.class.cast(testSrcDirs)) {
93 addFilePath(testDirectories, dir);
100 IdeaCompilerOutputImpl compilerOutput = new IdeaCompilerOutputImpl();
102 if (project.hasProperty(SOURCE_SETS_PROPERTY)) {
103 Object sourceSets = project.property(SOURCE_SETS_PROPERTY);
104 if (sourceSets instanceof SourceSetContainer) {
105 SourceSetContainer sourceSetContainer = (SourceSetContainer)sourceSets;
106 for (SourceSet sourceSet : sourceSetContainer) {
108 SourceSetOutput output = sourceSet.getOutput();
109 if (SourceSet.TEST_SOURCE_SET_NAME.equals(sourceSet.getName())) {
110 compilerOutput.setTestClassesDir(output.getClassesDir());
111 compilerOutput.setTestResourcesDir(output.getResourcesDir());
113 if (SourceSet.MAIN_SOURCE_SET_NAME.equals(sourceSet.getName())) {
114 compilerOutput.setMainClassesDir(output.getClassesDir());
115 compilerOutput.setMainResourcesDir(output.getResourcesDir());
118 for (File javaSrcDir : sourceSet.getAllJava().getSrcDirs()) {
119 boolean isTestDir = isTestDir(sourceSet, testClassesDirs);
120 addFilePath(isTestDir ? testDirectories : sourceDirectories, javaSrcDir);
122 for (File resourcesSrcDir : sourceSet.getResources().getSrcDirs()) {
123 boolean isTestDir = isTestDir(sourceSet, testClassesDirs);
124 addFilePath(isTestDir ? testResourceDirectories : resourceDirectories, resourcesSrcDir);
130 File projectDir = project.getProjectDir();
131 IdeaContentRootImpl contentRoot = new IdeaContentRootImpl(projectDir);
133 final Set<String> ideaSourceDirectories = new HashSet<String>();
134 final Set<String> ideaTestDirectories = new HashSet<String>();
135 final Set<String> ideaGeneratedDirectories = new HashSet<String>();
136 final Set<File> excludeDirectories = new HashSet<File>();
138 enrichDataFromIdeaPlugin(project, excludeDirectories, ideaSourceDirectories, ideaTestDirectories, ideaGeneratedDirectories);
140 if (ideaSourceDirectories.isEmpty()) {
141 sourceDirectories.clear();
142 resourceDirectories.clear();
144 if (ideaTestDirectories.isEmpty()) {
145 testDirectories.clear();
146 testResourceDirectories.clear();
149 ideaSourceDirectories.removeAll(resourceDirectories);
150 sourceDirectories.removeAll(ideaTestDirectories);
151 sourceDirectories.addAll(ideaSourceDirectories);
152 ideaTestDirectories.removeAll(testResourceDirectories);
153 testDirectories.addAll(ideaTestDirectories);
155 // ensure disjoint directories with different type
156 resourceDirectories.removeAll(sourceDirectories);
157 testDirectories.removeAll(sourceDirectories);
158 testResourceDirectories.removeAll(testDirectories);
160 for (String javaDir : sourceDirectories) {
161 contentRoot.addSourceDirectory(new IdeaSourceDirectoryImpl(new File(javaDir), ideaGeneratedDirectories.contains(javaDir)));
163 for (String testDir : testDirectories) {
164 contentRoot.addTestDirectory(new IdeaSourceDirectoryImpl(new File(testDir), ideaGeneratedDirectories.contains(testDir)));
166 for (String resourceDir : resourceDirectories) {
167 contentRoot.addResourceDirectory(new IdeaSourceDirectoryImpl(new File(resourceDir)));
169 for (String testResourceDir : testResourceDirectories) {
170 contentRoot.addTestResourceDirectory(new IdeaSourceDirectoryImpl(new File(testResourceDir)));
172 for (File excludeDir : excludeDirectories) {
173 contentRoot.addExcludeDirectory(excludeDir);
176 moduleVersionModel.setContentRoots(Collections.<ExtIdeaContentRoot>singleton(contentRoot));
177 moduleVersionModel.setCompilerOutput(compilerOutput);
178 return moduleVersionModel;
183 public ErrorMessageBuilder getErrorMessageBuilder(@NotNull Project project, @NotNull Exception e) {
184 return ErrorMessageBuilder.create(
186 ).withDescription("Unable to resolve all content root directories");
189 private static boolean isTestDir(SourceSet sourceSet, List<File> testClassesDirs) {
190 if (SourceSet.TEST_SOURCE_SET_NAME.equals(sourceSet.getName())) return true;
191 if (SourceSet.MAIN_SOURCE_SET_NAME.equals(sourceSet.getName())) return false;
193 File sourceSetClassesDir = sourceSet.getOutput().getClassesDir();
194 for (File testClassesDir : testClassesDirs) {
196 if (sourceSetClassesDir.getPath().equals(testClassesDir.getPath())) return true;
198 while ((testClassesDir = testClassesDir.getParentFile()) != null);
204 private static void addFilePath(Set<String> filePathSet, Object file) {
205 if (file instanceof File) {
207 filePathSet.add(((File)file).getCanonicalPath());
209 catch (IOException ignore) {
214 private static void enrichDataFromIdeaPlugin(Project project,
215 Set<File> excludeDirectories,
216 Set<String> javaDirectories,
217 Set<String> testDirectories,
218 Set<String> ideaGeneratedDirectories) {
220 IdeaPlugin ideaPlugin = project.getPlugins().getPlugin(IdeaPlugin.class);
221 if (ideaPlugin == null) return;
223 IdeaModel ideaModel = ideaPlugin.getModel();
224 if (ideaModel == null || ideaModel.getModule() == null) return;
226 for (File excludeDir : ideaModel.getModule().getExcludeDirs()) {
227 excludeDirectories.add(excludeDir);
229 for (File file : ideaModel.getModule().getSourceDirs()) {
230 javaDirectories.add(file.getPath());
232 for (File file : ideaModel.getModule().getTestSourceDirs()) {
233 testDirectories.add(file.getPath());
236 if(GradleVersion.current().compareTo(GradleVersion.version("2.2")) >=0) {
237 for (File file : ideaModel.getModule().getGeneratedSourceDirs()) {
238 ideaGeneratedDirectories.add(file.getPath());