package org.netbeans.gradle.project.model;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.gradle.tooling.BuildException;
import org.gradle.tooling.GradleConnectionException;
import org.gradle.tooling.GradleConnector;
import org.gradle.tooling.LongRunningOperation;
import org.gradle.tooling.ModelBuilder;
import org.gradle.tooling.ProjectConnection;
import org.gradle.tooling.internal.consumer.DefaultGradleConnector;
import org.gradle.tooling.model.build.BuildEnvironment;
import org.gradle.util.GradleVersion;
import org.jtrim.cancel.Cancellation;
import org.jtrim.cancel.CancellationToken;
import org.jtrim.concurrent.CancelableTask;
import org.jtrim.concurrent.MonitorableTaskExecutorService;
import org.jtrim.concurrent.TaskExecutor;
import org.jtrim.concurrent.Tasks;
import org.jtrim.property.PropertySource;
import org.jtrim.utils.ExceptionHelper;
import org.netbeans.api.progress.ProgressHandle;
import org.netbeans.api.project.Project;
import org.netbeans.gradle.model.BuildOperationArgs;
import org.netbeans.gradle.model.OperationInitializer;
import org.netbeans.gradle.project.LoadedProjectManager;
import org.netbeans.gradle.project.NbGradleProject;
import org.netbeans.gradle.project.NbGradleProjectFactory;
import org.netbeans.gradle.project.NbStrings;
import org.netbeans.gradle.project.api.config.PropertyReference;
import org.netbeans.gradle.project.api.modelquery.GradleTarget;
import org.netbeans.gradle.project.api.task.CommandCompleteListener;
import org.netbeans.gradle.project.api.task.DaemonTaskContext;
import org.netbeans.gradle.project.extensions.NbGradleExtensionRef;
import org.netbeans.gradle.project.model.issue.ModelLoadIssue;
import org.netbeans.gradle.project.model.issue.ModelLoadIssueReporter;
import org.netbeans.gradle.project.model.issue.ModelLoadIssues;
import org.netbeans.gradle.project.properties.GradleLocation;
import org.netbeans.gradle.project.properties.GradleLocationDef;
import org.netbeans.gradle.project.properties.GradleLocationDefault;
import org.netbeans.gradle.project.properties.ModelLoadingStrategy;
import org.netbeans.gradle.project.properties.NbGradleCommonProperties;
import org.netbeans.gradle.project.properties.global.CommonGlobalSettings;
import org.netbeans.gradle.project.script.ScriptFileProvider;
import org.netbeans.gradle.project.tasks.DaemonTask;
import org.netbeans.gradle.project.tasks.GradleArguments;
import org.netbeans.gradle.project.tasks.GradleDaemonFailures;
import org.netbeans.gradle.project.tasks.GradleDaemonManager;
import org.netbeans.gradle.project.tasks.GradleTasks;
import org.netbeans.gradle.project.tasks.vars.StringResolver;
import org.netbeans.gradle.project.tasks.vars.StringResolvers;
import org.netbeans.gradle.project.util.GradleVersions;
import org.netbeans.gradle.project.util.NbFunction;
import org.netbeans.gradle.project.util.NbSupplier;
import org.netbeans.gradle.project.util.NbTaskExecutors;
import org.netbeans.gradle.project.view.GlobalErrorReporter;
import org.openide.util.Lookup;
public final class DefaultGradleModelLoader implements ModelLoader<NbGradleModel> {
private static final Logger LOGGER = Logger.getLogger(DefaultGradleModelLoader.class.getName());
private static final TaskExecutor DEFAULT_PROJECT_LOADER
= NbTaskExecutors.newExecutor("Gradle-Project-Loader", 1);
private static final MonitorableTaskExecutorService DEFAULT_MODEL_LOAD_NOTIFIER
= NbTaskExecutors.newExecutor("Gradle-Project-Load-Notifier", 1);
private static final MonitorableTaskExecutorService DEFAULT_MODEL_PERSISTER
= NbTaskExecutors.newExecutor("Gradle-Project-Model-Persister", 1);
private static final AtomicReference<GradleModelCache> DEFAULT_CACHE_REF
= new AtomicReference<>(null);
private final NbGradleProject project;
private final TaskExecutor projectLoader;
private final MonitorableTaskExecutorService modelLoadNotifier;
private final LoadedProjectManager loadedProjectManager;
private final PersistentModelCache<NbGradleModel> persistentCache;
private final NbSupplier<? extends GradleModelCache> cacheRef;
private final CacheSizeIncreaser cacheSizeIncreaser;
private final AtomicBoolean modelWasSetOnce;
private DefaultGradleModelLoader(Builder builder) {
this.project = builder.project;
this.projectLoader = builder.projectLoader;
this.modelLoadNotifier = builder.modelLoadNotifier;
this.loadedProjectManager = builder.loadedProjectManager;
this.persistentCache = builder.persistentCache;
this.cacheRef = builder.cacheRef;
this.cacheSizeIncreaser = builder.cacheSizeIncreaser;
this.modelWasSetOnce = new AtomicBoolean(false);
}
private static void updateProjectFromCacheIfNeeded(NbGradleModel newModel) {
File projectDir = newModel.getProjectDir();
NbGradleProject project = LoadedProjectManager.getDefault().tryGetLoadedProject(projectDir);
if (project != null) {
project.tryReplaceModel(newModel);
}
}
private static GradleModelCache getDefaultCache() {
GradleModelCache result = DEFAULT_CACHE_REF.get();
if (result == null) {
final PropertySource<Integer> cacheSize = CommonGlobalSettings.getDefault().projectCacheSize().getActiveSource();
result = new GradleModelCache(cacheSize.getValue());
if (DEFAULT_CACHE_REF.compareAndSet(null, result)) {
final GradleModelCache cache = result;
cacheSize.addChangeListener(new Runnable() {
@Override
public void run() {
cache.setMaxCapacity(cacheSize.getValue());
}
});
cache.setMaxCapacity(cacheSize.getValue());
cache.addModelUpdateListener(new ProjectModelUpdatedListener() {
@Override
public void onUpdateProject(NbGradleModel newModel) {
updateProjectFromCacheIfNeeded(newModel);
}
});
}
else {
result = DEFAULT_CACHE_REF.get();
}
}
return result;
}
private GradleModelCache getCache() {
return cacheRef.get();
}
private static boolean hasWrapper(NbGradleProject project) {
Path rootDir = getProjectLoadKey(project).getAppliedRootProjectDir();
Path wrapperPropertiesFile = rootDir
.resolve("gradle")
.resolve("wrapper")
.resolve("gradle-wrapper.properties");
return Files.isRegularFile(wrapperPropertiesFile);
}
private static boolean shouldRelyOnWrapper(NbGradleProject project, GradleLocationDef locationDef) {
if (locationDef.getLocationRef() == GradleLocationDefault.DEFAULT_REF) {
return true;
}
return locationDef.isPreferWrapper() && hasWrapper(project);
}
public static GradleConnector createGradleConnector(
CancellationToken cancelToken,
final Project project) {
ExceptionHelper.checkNotNullArgument(cancelToken, "cancelToken");
ExceptionHelper.checkNotNullArgument(project, "project");
final GradleConnector result = GradleConnector.newConnector();
Integer timeoutSec = CommonGlobalSettings.getDefault().gradleDaemonTimeoutSec().getActiveValue();
if (timeoutSec != null && result instanceof DefaultGradleConnector) {
((DefaultGradleConnector)result).daemonMaxIdleTime(timeoutSec, TimeUnit.SECONDS);
}
NbGradleProject gradleProject = NbGradleProjectFactory.getGradleProject(project);
File gradleUserHome = CommonGlobalSettings.getDefault().gradleUserHomeDir().getActiveValue();
if (gradleUserHome != null) {
result.useGradleUserHomeDir(gradleUserHome);
}
NbGradleCommonProperties commonProperties = gradleProject.getCommonProperties();
GradleLocationDef gradleLocationDef = commonProperties.gradleLocation().getActiveValue();
if (!shouldRelyOnWrapper(gradleProject, gradleLocationDef)) {
StringResolver resolver = StringResolvers.getDefaultResolverSelector().getProjectResolver(gradleProject, Lookup.EMPTY);
GradleLocation gradleLocation = gradleLocationDef.getLocation(resolver);
gradleLocation.applyLocation(new GradleLocation.Applier() {
@Override
public void applyVersion(String versionStr) {
result.useGradleVersion(versionStr);
}
@Override
public void applyDirectory(File gradleHome) {
result.useInstallation(gradleHome);
}
@Override
public void applyDistribution(URI location) {
result.useDistribution(location);
}
@Override
public void applyDefault() {
}
});
}
return result;
}
private static ProjectLoadRequest getProjectLoadKey(NbGradleProject project) {
SettingsGradleDef settingsFile = project.getPreferredSettingsGradleDef();
return new ProjectLoadRequest(project, settingsFile);
}
private NbGradleModel tryGetFromCache(ProjectLoadRequest loadRequest) {
File settingsFile = loadRequest.findAppliedSettingsFileAsFile();
return getCache().tryGet(loadRequest.project.getProjectDirectoryAsFile(), settingsFile);
}
public static List<NbGradleExtensionRef> getUnloadedExtensions(
NbGradleProject project,
NbGradleModel baseModels) {
List<NbGradleExtensionRef> result = new ArrayList<>();
for (NbGradleExtensionRef extension: project.getExtensions().getExtensionRefs()) {
if (!baseModels.hasModelOfExtension(extension)) {
result.add(extension);
}
}
return result;
}
private boolean hasUnloadedExtension(NbGradleModel cached) {
for (NbGradleExtensionRef extension: project.getExtensions().getExtensionRefs()) {
if (!cached.hasModelOfExtension(extension)) {
return true;
}
}
return false;
}
private void onModelLoaded(
final NbGradleModel model,
final Throwable error,
final ModelRetrievedListener<? super NbGradleModel> listener) {
if (model == null && error == null) {
return;
}
modelWasSetOnce.set(true);
if (modelLoadNotifier.isExecutingInThis()) {
listener.updateModel(model, error);
}
else {
modelLoadNotifier.execute(Cancellation.UNCANCELABLE_TOKEN, new CancelableTask() {
@Override
public void execute(CancellationToken cancelToken) {
listener.updateModel(model, error);
}
}, null);
}
}
private static void reportModelLoadError(NbGradleProject project, GradleModelLoadError error) {
Throwable unexpectedError = error.getUnexpectedError();
if (unexpectedError != null) {
ModelLoadIssue unexpectedIssue = ModelLoadIssues
.projectModelLoadError(project, null, null, unexpectedError);
ModelLoadIssueReporter.reportAllIssues(Collections.singleton(unexpectedIssue));
}
Throwable buildScriptEvaluationError = error.getBuildScriptEvaluationError();
if (buildScriptEvaluationError != null) {
ModelLoadIssueReporter.reportBuildScriptError(project, buildScriptEvaluationError);
}
}
private NbGradleModel tryGetFromPersistentCache(ProjectLoadRequest projectLoadKey) {
if (modelWasSetOnce.get()) {
return null;
}
try {
return persistentCache.tryGetModel(projectLoadKey.getPersistentModelKey());
} catch (IOException ex) {
LOGGER.log(Level.INFO,
"Failed to read persistent cache for project " + projectLoadKey.project.getProjectDirectoryAsFile(),
ex);
} catch (Throwable ex) {
LOGGER.log(Level.SEVERE,
"Unexpected error while trying to read the persistent cache for project " + projectLoadKey.project.getProjectDirectoryAsFile(),
ex);
}
return null;
}
@Override
public void fetchModel(
final boolean mayFetchFromCache,
final ModelRetrievedListener<? super NbGradleModel> listener,
final Runnable aboutToCompleteListener) {
ExceptionHelper.checkNotNullArgument(listener, "listener");
ExceptionHelper.checkNotNullArgument(aboutToCompleteListener, "aboutToCompleteListener");
if (modelWasSetOnce.get()) {
fetchModelWithoutPersistentCache(mayFetchFromCache, listener, aboutToCompleteListener);
return;
}
modelLoadNotifier.execute(Cancellation.UNCANCELABLE_TOKEN, new CancelableTask() {
@Override
public void execute(CancellationToken cancelToken) {
NbGradleModel model = null;
boolean needLoadFromScripts = true;
try {
ProjectLoadRequest projectLoadKey = getProjectLoadKey(project);
model = mayFetchFromCache ? tryGetFromCache(projectLoadKey) : null;
if (model == null || hasUnloadedExtension(model)) {
model = tryGetFromPersistentCache(projectLoadKey);
}
else {
needLoadFromScripts = false;
}
} finally {
onModelLoaded(model, null, listener);
if (needLoadFromScripts) {
fetchModelWithoutPersistentCache(mayFetchFromCache, listener, aboutToCompleteListener);
}
}
}
}, null);
}
private static boolean isInProjectTree(NbGradleProject project, NbGradleModel rootModel) {
NbGradleProjectTree projectTree = rootModel.getGenericInfo().getProjectDef().getRootProject();
return isInProjectTree(project.getProjectDirectoryAsFile(), projectTree);
}
private static boolean isInProjectTree(File projectDir, NbGradleProjectTree projectTree) {
if (Objects.equals(projectDir, projectTree.getProjectDir())) {
return true;
}
for (NbGradleProjectTree child: projectTree.getChildren()) {
if (isInProjectTree(projectDir, child)) {
return true;
}
}
return false;
}
private ProjectLoadRequest fixProjectLoadKey(
CancellationToken cancelToken,
ProjectLoadRequest projectLoadKey,
ProgressHandle progress) throws IOException, GradleModelLoadError {
if (!CommonGlobalSettings.getDefault().loadRootProjectFirst().getActiveValue()) {
return projectLoadKey;
}
Path rootProjectDir = projectLoadKey.getAppliedRootProjectDir();
NbGradleProject rootProject = NbGradleProjectFactory.tryLoadSafeGradleProject(rootProjectDir);
if (rootProject == null) {
LOGGER.log(Level.INFO, "Failed to load root project for {0}.", project.getProjectDirectoryAsPath());
return projectLoadKey;
}
ProjectLoadRequest rootLoadKey = new ProjectLoadRequest(rootProject, projectLoadKey.settingsGradleDef);
NbGradleModel rootModel = tryGetFromCache(rootLoadKey);
if (rootModel == null || !isUpToDateModel(rootModel, project.getProjectDirectoryAsPath())) {
if (rootModel != null) {
LOGGER.log(Level.INFO,
"Reloading the guessed root project of {0} because its project directory was created after parsing the root project.",
project.getProjectDirectoryAsPath());
}
rootModel = loadModelWithProgress(cancelToken, rootLoadKey, progress, null);
assert rootModel != null;
}
if (!isInProjectTree(project, rootModel)) {
LOGGER.log(Level.INFO, "Project ({0}) is not found in the project tree of {1}. Assuming the project to be a single separate project.",
new Object[]{project.getProjectDirectoryAsFile(), rootModel.getProjectDir()});
return new ProjectLoadRequest(project, SettingsGradleDef.NO_SETTINGS);
}
return projectLoadKey;
}
private static boolean isUpToDateModel(NbGradleModel rootModel, Path dir) {
try {
BasicFileAttributes attrs = Files.readAttributes(dir, BasicFileAttributes.class);
FileTime creationTime = attrs.creationTime();
if (creationTime == null) {
return true;
}
return rootModel.getGenericInfo().getCreateTimeEpochMs() >= creationTime.toMillis();
} catch (IOException ex) {
return true;
}
}
private CommandCompleteListener projectTaskCompleteListener(final Runnable loadCompletedListener) {
return new CommandCompleteListener() {
@Override
public void onComplete(Throwable error) {
try {
GradleTasks.projectTaskCompleteListener(project).onComplete(error);
} finally {
loadCompletedListener.run();
}
}
};
}
private void fetchModelWithoutPersistentCache(
final boolean mayFetchFromCache,
final ModelRetrievedListener<? super NbGradleModel> listener,
Runnable aboutToCompleteListener) {
final Runnable safeCompleteListener = Tasks.runOnceTask(aboutToCompleteListener, false);
String caption = NbStrings.getLoadingProjectText(project.getDisplayName());
GradleDaemonManager.submitGradleTask(projectLoader, caption, new DaemonTask() {
@Override
public void run(CancellationToken cancelToken, ProgressHandle progress) {
ProjectLoadRequest projectLoadKey = getProjectLoadKey(project);
NbGradleModel model = null;
Throwable error = null;
try {
ProjectLoadRequest fixedLoadKey = fixProjectLoadKey(cancelToken, projectLoadKey, progress);
if (mayFetchFromCache) {
model = tryGetFromCache(fixedLoadKey);
}
if (model == null || hasUnloadedExtension(model)) {
model = loadModelWithProgress(cancelToken, fixedLoadKey, progress, model);
}
} catch (IOException | BuildException ex) {
error = ex;
} catch (GradleConnectionException ex) {
error = ex;
} catch (GradleModelLoadError ex) {
error = ex;
reportModelLoadError(project, ex);
} finally {
safeCompleteListener.run();
onModelLoaded(model, error, listener);
if (error != null) {
GradleDaemonFailures.getDefaultHandler().tryHandleFailure(error);
}
}
}
}, true, projectTaskCompleteListener(safeCompleteListener));
}
private void saveToPersistentCache(Collection<NbGradleModel> models) {
try {
persistentCache.saveGradleModels(models);
} catch (IOException ex) {
LOGGER.log(Level.INFO, "Failed to save into the persistent cache.", ex);
} catch (Throwable ex) {
LOGGER.log(Level.SEVERE, "Unexpected error while saving to the persistent cache.", ex);
}
}
private NbGradleModel introduceLoadedModel(NbGradleModel model, boolean replaced) {
NbGradleModel modelToSave;
if (replaced) {
modelToSave = model;
getCache().replaceEntry(model);
}
else {
modelToSave = getCache().updateEntry(model);
}
NbGradleProject ownerProject = loadedProjectManager.tryGetLoadedProject(model.getProjectDir());
if (ownerProject != null) {
ownerProject.tryReplaceModel(modelToSave);
}
return modelToSave;
}
private void introduceProjects(
List<NbGradleModel> otherModels,
NbGradleModel mainModel) {
int numberOfModels = otherModels.size() + 1;
// Required one more than actually needed to create room for a buildSrc project.
cacheSizeIncreaser.requiresCacheSize(getCache(), numberOfModels + 1);
List<NbGradleModel> toSave = new ArrayList<>(numberOfModels);
for (NbGradleModel model: otherModels) {
toSave.add(introduceLoadedModel(model, false));
}
toSave.add(introduceLoadedModel(mainModel, true));
saveToPersistentCache(toSave);
}
public static void setupLongRunningOP(OperationInitializer setup, LongRunningOperation op) {
BuildOperationArgs args = new BuildOperationArgs();
setup.initOperation(args);
args.setupLongRunningOP(op);
}
private static DaemonTaskContext daemonTaskContext(Project project) {
return new DaemonTaskContext(project, true);
}
private static List<String> getModelEvaluateJvmArguments(Project project) {
return GradleArguments.getExtraJvmArgs(daemonTaskContext(project));
}
private static DefaultModelBuilderSetup modelBuilderSetup(ProjectLoadRequest projectLoadKey, ProgressHandle progress) {
return new DefaultModelBuilderSetup(
projectLoadKey.project,
getModelEvaluateArguments(projectLoadKey),
getModelEvaluateJvmArguments(projectLoadKey.project),
progress);
}
public static DefaultModelBuilderSetup modelBuilderSetup(NbGradleProject project, ProgressHandle progress) {
return modelBuilderSetup(getProjectLoadKey(project), progress);
}
public static DefaultModelBuilderSetup modelBuilderSetup(Project project, ProgressHandle progress) {
NbGradleProject gradleProject = NbGradleProjectFactory.tryGetGradleProject(project);
if (gradleProject != null) {
return modelBuilderSetup(gradleProject, progress);
}
// This path should not be taken under normal circumstances.
// That is, this path is only taken if for some weird reasons a non-gradle
// project is being interpreted as a Gradle project.
return new DefaultModelBuilderSetup(
project,
getModelEvaluateArguments(project, SettingsGradleDef.DEFAULT),
getModelEvaluateJvmArguments(project),
progress);
}
private NbGradleModel loadModelWithProgress(
CancellationToken cancelToken,
final ProjectLoadRequest projectLoadKey,
final ProgressHandle progress,
final NbGradleModel cachedEntry) throws IOException, GradleModelLoadError {
File projectDir = project.getProjectDirectoryAsFile();
LOGGER.log(Level.INFO,
"Loading Gradle project from directory: {0}, settings.gradle: {1}",
new Object[]{projectDir, projectLoadKey.settingsGradleDef});
GradleConnector gradleConnector = createGradleConnector(cancelToken, project);
gradleConnector.forProjectDirectory(projectDir);
ProjectConnection projectConnection = null;
NbModelLoader.Result loadedModels;
try {
projectConnection = gradleConnector.connect();
DefaultModelBuilderSetup setup = modelBuilderSetup(projectLoadKey, progress);
ModelBuilder<BuildEnvironment> modelBuilder = projectConnection.model(BuildEnvironment.class);
setupLongRunningOP(setup, modelBuilder);
BuildEnvironment env = modelBuilder.get();
reportKnownIssues(env);
GradleTarget gradleTarget = new GradleTarget(
setup.getJDKVersion(),
GradleVersion.version(env.getGradle().getGradleVersion()));
NbModelLoader modelLoader = chooseModel(projectLoadKey.settingsGradleDef, gradleTarget, cachedEntry, setup);
loadedModels = modelLoader.loadModels(project, projectConnection, progress);
} finally {
if (projectConnection != null) {
projectConnection.close();
}
}
ModelLoadIssueReporter.reportAllIssues(loadedModels.getIssues());
NbGradleModel result = cachedEntry != null
? cachedEntry.updateEntry(loadedModels.getMainModel())
: loadedModels.getMainModel();
introduceProjects(loadedModels.getOtherModels(), result);
return result;
}
private static void reportKnownIssues(BuildEnvironment env) {
GradleVersion version = GradleVersion.version(env.getGradle().getGradleVersion());
if (GradleVersions.VERSION_1_7.compareTo(version) < 0
&& GradleVersions.VERSION_1_8.compareTo(version) >= 0) {
String gradleVersion = env.getGradle().getGradleVersion();
GlobalErrorReporter.showIssue(NbStrings.getIssueWithGradle18Message(gradleVersion));
}
else if (GradleVersions.VERSION_2_3.equals(version.getBaseVersion())) {
String gradleVersion = env.getGradle().getGradleVersion();
GlobalErrorReporter.showIssue(NbStrings.getIssueWithGradle23Message(gradleVersion));
}
}
private static NbModelLoader chooseModel(
SettingsGradleDef settingsGradleDef,
GradleTarget gradleTarget,
NbGradleModel cachedModel,
OperationInitializer setup) {
GradleVersion version = gradleTarget.getGradleVersion();
ModelLoadingStrategy modelLoadingStrategy = CommonGlobalSettings.getDefault().modelLoadingStrategy().getActiveValue();
NbModelLoader result = modelLoadingStrategy.canUse18Api(version)
? new NbGradle18ModelLoader(settingsGradleDef, setup, gradleTarget)
: new NbCompatibleModelLoader(settingsGradleDef, cachedModel, setup, gradleTarget);
LOGGER.log(Level.INFO, "Using model loader: {0}", result.getClass().getSimpleName());
return result;
}
public static NbGradleModel createEmptyModel(Path projectDir, ScriptFileProvider scriptProvider) {
return new NbGradleModel(
NbGradleMultiProjectDef.createEmpty(projectDir, scriptProvider),
scriptProvider);
}
private static List<String> getModelEvaluateArguments(Project project, SettingsGradleDef settingsDef) {
return GradleArguments.getExtraArgs(settingsDef, daemonTaskContext(project));
}
private static List<String> getModelEvaluateArguments(ProjectLoadRequest projectLoadKey) {
return GradleArguments.getExtraArgs(
projectLoadKey.settingsGradleDef,
daemonTaskContext(projectLoadKey.project));
}
public static void ensureCacheSize(int minimumCacheSize) {
ensureCacheSize(getDefaultCache(), minimumCacheSize);
}
private static void ensureCacheSize(GradleModelCache cache, int minimumCacheSize) {
if (cache.getMaxCapacity() >= minimumCacheSize) {
return;
}
PropertyReference<Integer> projectCacheSize = CommonGlobalSettings.getDefault().projectCacheSize();
Integer prevCacheSize = projectCacheSize.getActiveValue();
if (prevCacheSize >= minimumCacheSize) {
return;
}
projectCacheSize.setValue(minimumCacheSize);
cache.setMaxCapacityToAtLeast(minimumCacheSize);
GlobalErrorReporter.showWarning(NbStrings.getTooSmallCache(prevCacheSize, minimumCacheSize));
}
public static final class Builder {
private static final PersistentProjectModelStoreFactory DEFAULT_MODEL_STORE_FACTORY
= new PersistentProjectModelStoreFactory();
private static final LazyPersistentModelStoreFactory<NbGradleModel> DEFAULT_LAZY_MODEL_STORE_FACTORY
= new LazyPersistentModelStoreFactory<>(DEFAULT_MODEL_STORE_FACTORY.getModelPersister(), DEFAULT_MODEL_PERSISTER);
private final NbGradleProject project;
private TaskExecutor projectLoader;
private MonitorableTaskExecutorService modelLoadNotifier;
private LoadedProjectManager loadedProjectManager;
private PersistentModelCache<NbGradleModel> persistentCache;
private NbSupplier<? extends GradleModelCache> cacheRef;
private CacheSizeIncreaser cacheSizeIncreaser;
public Builder(NbGradleProject project) {
ExceptionHelper.checkNotNullArgument(project, "project");
this.project = project;
this.projectLoader = DEFAULT_PROJECT_LOADER;
this.modelLoadNotifier = DEFAULT_MODEL_LOAD_NOTIFIER;
this.loadedProjectManager = LoadedProjectManager.getDefault();
this.persistentCache = new MultiFileModelCache<>(defaultModelPersister(project), new NbFunction<NbGradleModel, PersistentModelKey>() {
@Override
public PersistentModelKey apply(NbGradleModel arg) {
try {
return new PersistentModelKey(arg).normalize();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
});
this.cacheRef = new NbSupplier<GradleModelCache>() {
@Override
public GradleModelCache get() {
return getDefaultCache();
}
};
this.cacheSizeIncreaser = new CacheSizeIncreaser() {
@Override
public void requiresCacheSize(GradleModelCache cache, int minimumCacheSize) {
ensureCacheSize(cache, minimumCacheSize);
}
};
}
private static PersistentModelStore<NbGradleModel> defaultModelPersister(NbGradleProject project) {
return DEFAULT_LAZY_MODEL_STORE_FACTORY.createStore(DEFAULT_MODEL_STORE_FACTORY.createModelStore(project));
}
public void setProjectLoader(TaskExecutor projectLoader) {
ExceptionHelper.checkNotNullArgument(projectLoader, "projectLoader");
this.projectLoader = projectLoader;
}
public void setModelLoadNotifier(MonitorableTaskExecutorService modelLoadNotifier) {
ExceptionHelper.checkNotNullArgument(modelLoadNotifier, "modelLoadNotifier");
this.modelLoadNotifier = modelLoadNotifier;
}
public void setLoadedProjectManager(LoadedProjectManager loadedProjectManager) {
ExceptionHelper.checkNotNullArgument(loadedProjectManager, "loadedProjectManager");
this.loadedProjectManager = loadedProjectManager;
}
public void setPersistentCache(PersistentModelCache<NbGradleModel> persistentCache) {
ExceptionHelper.checkNotNullArgument(persistentCache, "persistentCache");
this.persistentCache = persistentCache;
}
public void setCacheRef(final GradleModelCache cache) {
ExceptionHelper.checkNotNullArgument(cache, "cache");
this.cacheRef = new NbSupplier<GradleModelCache>() {
@Override
public GradleModelCache get() {
return cache;
}
};
}
public DefaultGradleModelLoader create() {
return new DefaultGradleModelLoader(this);
}
}
private static final class ProjectLoadRequest {
public final NbGradleProject project;
public final SettingsGradleDef settingsGradleDef;
public ProjectLoadRequest(NbGradleProject project, SettingsGradleDef settingsGradleDef) {
assert project != null;
assert settingsGradleDef != null;
this.project = project;
this.settingsGradleDef = settingsGradleDef;
}
public PersistentModelKey getPersistentModelKey() throws IOException {
return new PersistentModelKey(getAppliedRootProjectDir(), project.getProjectDirectoryAsPath()).normalize();
}
public File findAppliedSettingsFileAsFile() {
Path result = findAppliedSettingsFile();
return result != null ? result.toFile() : null;
}
public Path findAppliedSettingsFile() {
Path settingsFile = settingsGradleDef.getSettingsGradle();
if (settingsFile != null) {
return settingsFile;
}
return NbGradleModel.findSettingsGradle(
project.getProjectDirectoryAsPath(),
project.getScriptFileProvider());
}
public Path getAppliedRootProjectDir() {
Path appliedSettingsFile = settingsGradleDef.getSettingsGradle();
if (appliedSettingsFile == null) {
appliedSettingsFile = findAppliedSettingsFile();
}
if (appliedSettingsFile != null) {
Path settingsFileDir = appliedSettingsFile.getParent();
if (settingsFileDir != null) {
return settingsFileDir;
}
}
return project.getProjectDirectoryAsPath();
}
}
}