package org.netbeans.gradle.project.java; import java.io.File; import java.io.IOException; import java.util.Collection; import java.util.Collections; import java.util.Map; import java.util.Set; import org.gradle.tooling.model.idea.IdeaProject; import org.netbeans.api.project.Project; import org.netbeans.gradle.model.java.JavaModelBuilders; import org.netbeans.gradle.model.util.CollectionUtils; import org.netbeans.gradle.project.NbGradleProjectFactory; import org.netbeans.gradle.project.api.entry.GradleProjectExtension2; import org.netbeans.gradle.project.api.entry.GradleProjectExtensionDef; import org.netbeans.gradle.project.api.entry.ModelLoadResult; import org.netbeans.gradle.project.api.entry.ParsedModel; import org.netbeans.gradle.project.api.modelquery.GradleModelDef; import org.netbeans.gradle.project.api.modelquery.GradleModelDefQuery1; import org.netbeans.gradle.project.api.modelquery.GradleModelDefQuery2; import org.netbeans.gradle.project.api.modelquery.GradleTarget; import org.netbeans.gradle.project.java.model.JavaModelSource; import org.netbeans.gradle.project.java.model.JavaParsingUtils; import org.netbeans.gradle.project.java.model.NbJavaModel; import org.netbeans.gradle.project.java.model.NbJavaModule; import org.netbeans.gradle.project.java.model.idea.IdeaJavaModelUtils; import org.netbeans.gradle.project.others.OtherPlugins; import org.netbeans.gradle.project.script.ScriptFileProvider; import org.openide.util.Lookup; import org.openide.util.lookup.Lookups; import org.openide.util.lookup.ServiceProvider; @ServiceProvider(service = GradleProjectExtensionDef.class, position = 1000) public final class JavaExtensionDef implements GradleProjectExtensionDef<NbJavaModel> { // Do not return JavaExtension.class.getName() because this string must // remain the same even if this class is renamed. public static final String EXTENSION_NAME = "org.netbeans.gradle.project.java.JavaExtension"; private final Lookup lookup; public JavaExtensionDef() { this.lookup = Lookups.fixed(new Query1(), new Query2()); } @Override public String getName() { return EXTENSION_NAME; } @Override public String getDisplayName() { return "J2SE"; } @Override public Lookup getLookup() { return lookup; } @Override public Class<NbJavaModel> getModelType() { return NbJavaModel.class; } private static NbJavaModel createReliableModel(GradleTarget evaluationEnvironment, NbJavaModule mainModule) { return NbJavaModel.createModel( evaluationEnvironment, JavaModelSource.GRADLE_1_8_API, mainModule); } private Map<File, NbJavaModel> parseFromNewModels(ModelLoadResult retrievedModels) { GradleTarget evaluationEnvironment = retrievedModels.getEvaluationEnvironment(); Collection<NbJavaModule> modules = JavaParsingUtils.parseModules(retrievedModels); Map<File, NbJavaModel> result = CollectionUtils.newHashMap(modules.size()); for (NbJavaModule module: modules) { NbJavaModel model = createReliableModel(evaluationEnvironment, module); result.put(module.getModuleDir(), model); } for (File projectDir: retrievedModels.getEvaluatedProjectsModel().keySet()) { if (!result.containsKey(projectDir)) { result.put(projectDir, null); } } return result; } private Map<File, NbJavaModel> parseFromIdeaProject( ModelLoadResult retrievedModels, IdeaProject ideaProject, ScriptFileProvider scriptProvider) throws IOException { return IdeaJavaModelUtils.parseFromIdeaModel( retrievedModels.getEvaluationEnvironment(), retrievedModels.getMainProjectDir(), ideaProject, scriptProvider); } private ParsedModel<NbJavaModel> parseModelImpl( ModelLoadResult retrievedModels, ScriptFileProvider scriptProvider) throws IOException { // FIXME: The specification allows IdeaProject to be available even // if did not request it, so this should be changed to use the // new models if they are available even if there is an IdeaProject. IdeaProject ideaProject = retrievedModels.getMainProjectModels().lookup(IdeaProject.class); Map<File, NbJavaModel> result = ideaProject != null ? parseFromIdeaProject(retrievedModels, ideaProject, scriptProvider) : parseFromNewModels(retrievedModels); NbJavaModel mainModule = result.get(retrievedModels.getMainProjectDir()); return new ParsedModel<>(mainModule, result); } @Override public ParsedModel<NbJavaModel> parseModel(ModelLoadResult retrievedModels) { try { return parseModelImpl(retrievedModels, NbGradleProjectFactory.DEFAULT_SCRIPT_FILE_PROVIDER); } catch (IOException ex) { throw new RuntimeException(ex); } } @Override public GradleProjectExtension2<NbJavaModel> createExtension(Project project) throws IOException { return JavaExtension.create(project); } @Override public Set<String> getSuppressedExtensions() { return Collections.emptySet(); } private static final class Query1 implements GradleModelDefQuery1 { private static final Collection<Class<?>> RESULT = Collections.<Class<?>>singleton(IdeaProject.class); @Override public Collection<Class<?>> getToolingModels(GradleTarget gradleTarget) { return RESULT; } } private static final class Query2 implements GradleModelDefQuery2 { private static final GradleModelDef RESULT = GradleModelDef.fromProjectInfoBuilders2( JavaModelBuilders.JAR_OUTPUTS_BUILDER, JavaModelBuilders.JAVA_SOURCES_BUILDER_COMPLETE, JavaModelBuilders.JAVA_COMPATIBILITY_BUILDER, JavaModelBuilders.JAVA_TEST_BUILDER, JavaModelBuilders.JACOCO_BUILDER, JavaModelBuilders.WAR_FOLDERS_BUILDER); private static final GradleModelDef RESULT_WITHOUT_WAR = GradleModelDef.fromProjectInfoBuilders2( JavaModelBuilders.JAR_OUTPUTS_BUILDER, JavaModelBuilders.JAVA_SOURCES_BUILDER_COMPLETE, JavaModelBuilders.JAVA_COMPATIBILITY_BUILDER, JavaModelBuilders.JAVA_TEST_BUILDER, JavaModelBuilders.JACOCO_BUILDER); @Override public GradleModelDef getModelDef(GradleTarget gradleTarget) { return OtherPlugins.hasJavaEEExtension() ? RESULT_WITHOUT_WAR : RESULT; } } }