package org.netbeans.gradle.project.api.modelquery; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; import javax.annotation.Nonnull; import org.jtrim.utils.ExceptionHelper; import org.netbeans.gradle.model.api.GradleProjectInfoQuery2; import org.netbeans.gradle.model.api.ModelClassPathDef; import org.netbeans.gradle.model.api.ProjectInfoBuilder2; import org.netbeans.gradle.model.util.BuilderUtils; import org.netbeans.gradle.model.util.CollectionUtils; import org.netbeans.gradle.model.util.CompatibilityUtils; /** * Defines the information needed from the Gradle daemon by an extension of the * Gradle plugin of NetBeans. * <P> * Currently, you can request the following information: * <ul> * <li>Simple models, such as {@link org.gradle.tooling.model.idea.IdeaProject}</li> * <li>Queries which can extract any information given a {@link org.gradle.api.Project} instance.</li> * </ul> * <P> * Note: In almost all cases, it is recommended to use one of the convenience factory * method: {@link #fromProjectInfoBuilders(ProjectInfoBuilder[]) fromProjectInfoBuilders}. * <P> * Instances of this class are immutable and therefore are safe to be shared * by multiple threads concurrently. * * @see GradleModelDefQuery2 */ public final class GradleModelDef { /** * An instance of {@code GradleModelDef} requesting no models. */ public static final GradleModelDef EMPTY = create( Collections.<Class<?>>emptySet(), Collections.<GradleProjectInfoQuery2<?>>emptySet()); private final Collection<Class<?>> toolingModels; private final Collection<GradleProjectInfoQuery2<?>> projectInfoQueries; /** * @deprecated Use {@link #create} instead because * {@code GradleProjectInfoQuery} is deprecated. * <P> * Creates a new {@code GradleModelDef} with the given requested information. * * @param toolingModels the Tooling API models to request from Gradle. For * example: {@code IdeaProject}. This argument cannot be {@code null} and * cannot contain {@code null} elements. * @param projectInfoQueries custom queries able to retrieve information * from a {@link org.gradle.api.Project} instance. This argument cannot be * {@code null} and cannot contain {@code null} elements. */ @Deprecated public GradleModelDef( @Nonnull Collection<? extends Class<?>> toolingModels, @Nonnull Collection<? extends org.netbeans.gradle.model.api.GradleProjectInfoQuery<?>> projectInfoQueries) { this(toolingModels, CompatibilityUtils.toQuery2All(projectInfoQueries), false); } private GradleModelDef( @Nonnull Collection<? extends Class<?>> toolingModels, @Nonnull Collection<? extends GradleProjectInfoQuery2<?>> projectInfoQueries, boolean x) { // argument x is only used because we need to overload the constructor this.toolingModels = CollectionUtils.copyNullSafeList(toolingModels); this.projectInfoQueries = CollectionUtils.copyNullSafeList(projectInfoQueries); } /** * Creates a new {@code GradleModelDef} with the given requested information. * * @param toolingModels the Tooling API models to request from Gradle. For * example: {@code IdeaProject}. This argument cannot be {@code null} and * cannot contain {@code null} elements. * @param projectInfoQueries custom queries able to retrieve information * from a {@link org.gradle.api.Project} instance. This argument cannot be * {@code null} and cannot contain {@code null} elements. * @return the new {@code GradleModelDef} with the given requested information. * This method never returns {@code null}. */ public static GradleModelDef create( @Nonnull Collection<? extends Class<?>> toolingModels, @Nonnull Collection<? extends GradleProjectInfoQuery2<?>> projectInfoQueries) { return new GradleModelDef(toolingModels, projectInfoQueries, true); } /** * Creates a new {@code GradleModelDef} with the given Tooling API models * and with no {@link #getProjectInfoQueries() custom queries}. * * @param modelTypes the Tooling API models to request from Gradle. For * example: {@code IdeaProject}. This argument cannot be {@code null} and * cannot contain {@code null} elements. * @return the new {@code GradleModelDef} with the given Tooling API models. * This method never returns {@code null}. */ @Nonnull public static GradleModelDef fromToolingModels(Class<?>... modelTypes) { return create( Arrays.asList(modelTypes), Collections.<GradleProjectInfoQuery2<?>>emptyList()); } /** * @deprecated Use {@link #fromProjectQueries2} instead because * {@code GradleProjectInfoQuery} is deprecated. * <P> * Creates a new {@code GradleModelDef} with the given custom queries and * with no {@link #getToolingModels() Tooling API models}. * * @param queries custom queries able to retrieve information * from a {@link org.gradle.api.Project} instance. This argument cannot be * {@code null} and cannot contain {@code null} elements. * @return the new {@code GradleModelDef} with the given custom queries. * This method never returns {@code null}. */ @Nonnull @Deprecated public static GradleModelDef fromProjectQueries(org.netbeans.gradle.model.api.GradleProjectInfoQuery<?>... queries) { return new GradleModelDef(Collections.<Class<?>>emptyList(), Arrays.asList(queries)); } /** * Creates a new {@code GradleModelDef} with the given custom queries and * with no {@link #getToolingModels() Tooling API models}. * * @param queries custom queries able to retrieve information * from a {@link org.gradle.api.Project} instance. This argument cannot be * {@code null} and cannot contain {@code null} elements. * @return the new {@code GradleModelDef} with the given custom queries. * This method never returns {@code null}. */ @Nonnull public static GradleModelDef fromProjectQueries2(GradleProjectInfoQuery2<?>... queries) { return create(Collections.<Class<?>>emptyList(), Arrays.asList(queries)); } /** * Creates a new {@code GradleModelDef} with the given custom * {@link ProjectInfoBuilder} instances and * {@link #getToolingModels() Tooling API models}. * <P> * <B>Warning</B>: This method assumes that for each builder, the builder * and its result are found in the same classpath entry (usually jar) and * can be deserialized using the {@code ClassLoader} used to load the class * of the builder. * * @param modelTypes the Tooling API models to request from Gradle. For * example: {@code IdeaProject}. This argument cannot be {@code null} and * cannot contain {@code null} elements. * @param builders custom builders able to retrieve information * from a {@link org.gradle.api.Project} instance. This argument cannot be * {@code null} and cannot contain {@code null} elements. * @return the new {@code GradleModelDef} with the given custom builders. * This method never returns {@code null}. */ @Nonnull public static GradleModelDef fromProjectInfoBuilders2( Collection<? extends Class<?>> modelTypes, ProjectInfoBuilder2<?>... builders) { List<GradleProjectInfoQuery2<?>> queries = new ArrayList<>(builders.length); for (ProjectInfoBuilder2<?> builder: builders) { queries.add(createDefaultQuery(builder)); } return GradleModelDef.create(modelTypes, queries); } /** * Creates a new {@code GradleModelDef} with the given custom * {@link ProjectInfoBuilder} instances and with no * {@link #getToolingModels() Tooling API models}. * <P> * <B>Warning</B>: This method assumes that for each builder, the builder * and its result are found in the same classpath entry (usually jar) and * can be deserialized using the {@code ClassLoader} used to load the class * of the builder. * * @param builders custom builders able to retrieve information * from a {@link org.gradle.api.Project} instance. This argument cannot be * {@code null} and cannot contain {@code null} elements. * @return the new {@code GradleModelDef} with the given custom builders. * This method never returns {@code null}. */ @Nonnull public static GradleModelDef fromProjectInfoBuilders2(ProjectInfoBuilder2<?>... builders) { return fromProjectInfoBuilders2(Collections.<Class<?>>emptySet(), builders); } /** * @deprecated Use {@link #fromProjectInfoBuilders2} instead because * {@code ProjectInfoBuilder} is deprecated. * <P> * Creates a new {@code GradleModelDef} with the given custom * {@link ProjectInfoBuilder} instances and * {@link #getToolingModels() Tooling API models}. * <P> * <B>Warning</B>: This method assumes that for each builder, the builder * and its result are found in the same classpath entry (usually jar) and * can be deserialized using the {@code ClassLoader} used to load the class * of the builder. * * @param modelTypes the Tooling API models to request from Gradle. For * example: {@code IdeaProject}. This argument cannot be {@code null} and * cannot contain {@code null} elements. * @param builders custom builders able to retrieve information * from a {@link org.gradle.api.Project} instance. This argument cannot be * {@code null} and cannot contain {@code null} elements. * @return the new {@code GradleModelDef} with the given custom builders. * This method never returns {@code null}. */ @Nonnull @Deprecated public static GradleModelDef fromProjectInfoBuilders( Collection<? extends Class<?>> modelTypes, org.netbeans.gradle.model.api.ProjectInfoBuilder<?>... builders) { return fromProjectInfoBuilders2(modelTypes, convertBuilders(builders)); } /** * @deprecated Use {@link #fromProjectInfoBuilders2} instead because * {@code ProjectInfoBuilder} is deprecated. * <P> * Creates a new {@code GradleModelDef} with the given custom * {@link ProjectInfoBuilder} instances and with no * {@link #getToolingModels() Tooling API models}. * <P> * <B>Warning</B>: This method assumes that for each builder, the builder * and its result are found in the same classpath entry (usually jar) and * can be deserialized using the {@code ClassLoader} used to load the class * of the builder. * * @param builders custom builders able to retrieve information * from a {@link org.gradle.api.Project} instance. This argument cannot be * {@code null} and cannot contain {@code null} elements. * @return the new {@code GradleModelDef} with the given custom builders. * This method never returns {@code null}. */ @Nonnull @Deprecated public static GradleModelDef fromProjectInfoBuilders(org.netbeans.gradle.model.api.ProjectInfoBuilder<?>... builders) { return fromProjectInfoBuilders2(Collections.<Class<?>>emptySet(), convertBuilders(builders)); } @SuppressWarnings("deprecation") private static ProjectInfoBuilder2<?>[] convertBuilders(org.netbeans.gradle.model.api.ProjectInfoBuilder<?>... builders) { ProjectInfoBuilder2<?>[] converted = new ProjectInfoBuilder2<?>[builders.length]; for (int i = 0; i < builders.length; i++) { converted[i] = CompatibilityUtils.toBuilder2(builders[i]); } return converted; } private static <T> GradleProjectInfoQuery2<T> createDefaultQuery(final ProjectInfoBuilder2<T> builder) { ExceptionHelper.checkNotNullArgument(builder, "builder"); final ModelClassPathDef classPathDef = BuilderUtils.getClassPathOfBuilder(builder); return new GradleProjectInfoQuery2<T>() { @Override public ProjectInfoBuilder2<T> getInfoBuilder() { return builder; } @Override public ModelClassPathDef getInfoClassPath() { return classPathDef; } }; } /** * Returns the requested simple Tooling API models. Examples of such models * are: {@link org.gradle.tooling.model.GradleProject}, * {@link org.gradle.tooling.model.idea.IdeaProject}. * * @return the requested simple Tooling API models. This method never * returns {@code null} and the returned collection does not contain * {@code null} elements. */ @Nonnull public Collection<Class<?>> getToolingModels() { return toolingModels; } /** * @deprecated Use {@link #getProjectInfoQueries2()} instead because * {@code GradleProjectInfoQuery} is deprecated. * <P> * Returns the custom queries the retrieve information from Gradle projects * from a {@link org.gradle.api.Project} instance. * * @return the custom queries the retrieve information from Gradle projects. * This method never returns {@code null} and the returned collection does * not contain {@code null} elements. */ @Nonnull @Deprecated public Collection<org.netbeans.gradle.model.api.GradleProjectInfoQuery<?>> getProjectInfoQueries() { return CompatibilityUtils.toQueryAll(projectInfoQueries); } /** * Returns the custom queries the retrieve information from Gradle projects * from a {@link org.gradle.api.Project} instance. * * @return the custom queries the retrieve information from Gradle projects. * This method never returns {@code null} and the returned collection does * not contain {@code null} elements. */ @Nonnull public Collection<GradleProjectInfoQuery2<?>> getProjectInfoQueries2() { return projectInfoQueries; } }