Skip to content

Commit bed58e3

Browse files
committed
Extract ClasspathContainerState from ClasspathComputer
With the enhanced storage/save of the classpath container state now the ClasspathComputer becomes more and more complex and contains too much different tasks. This extracts from the ClasspathComputer the parts that handle the state into new class ClasspathContainerState to make it more maintainable.
1 parent 4c4ad88 commit bed58e3

10 files changed

Lines changed: 310 additions & 277 deletions

File tree

ds/org.eclipse.pde.ds.annotations/src/org/eclipse/pde/ds/internal/annotations/DSAnnotationPreferenceListener.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
3131
import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
3232
import org.eclipse.core.runtime.preferences.InstanceScope;
33-
import org.eclipse.pde.internal.core.ClasspathComputer;
33+
import org.eclipse.pde.internal.core.ClasspathContainerState;
3434
import org.eclipse.pde.internal.core.PluginModelManager;
3535
import org.eclipse.swt.widgets.Display;
3636
import org.eclipse.ui.PlatformUI;
@@ -66,7 +66,7 @@ public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
6666
SubMonitor progress = SubMonitor.convert(monitor, Messages.DSAnnotationPreferenceListener_taskName,
6767
managedProjects.size() * 2);
6868
if (requiresClasspathUpdate) {
69-
ClasspathComputer.requestClasspathUpdate(managedProjects);
69+
ClasspathContainerState.requestClasspathUpdate(managedProjects);
7070
try {
7171
Job.getJobManager().join(PluginModelManager.class, monitor);
7272
} catch (OperationCanceledException | InterruptedException e) {

ds/org.eclipse.pde.ds.annotations/src/org/eclipse/pde/ds/internal/annotations/DSLibPluginModelListener.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import org.eclipse.core.resources.IProject;
2222
import org.eclipse.jdt.core.IJavaProject;
2323
import org.eclipse.pde.core.plugin.ModelEntry;
24-
import org.eclipse.pde.internal.core.ClasspathComputer;
24+
import org.eclipse.pde.internal.core.ClasspathContainerState;
2525
import org.eclipse.pde.internal.core.IPluginModelListener;
2626
import org.eclipse.pde.internal.core.PluginModelDelta;
2727
import org.eclipse.pde.internal.core.PluginModelManager;
@@ -116,7 +116,7 @@ && containsModel(delta.getRemovedEntries(), modelId))) {
116116
}
117117
}
118118
}
119-
ClasspathComputer.requestClasspathUpdate(toUpdate);
119+
ClasspathContainerState.requestClasspathUpdate(toUpdate);
120120
}
121121
}
122122

ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/ClasspathComputer.java

Lines changed: 0 additions & 262 deletions
Original file line numberDiff line numberDiff line change
@@ -13,43 +13,24 @@
1313
*******************************************************************************/
1414
package org.eclipse.pde.internal.core;
1515

16-
import java.io.BufferedOutputStream;
17-
import java.io.File;
18-
import java.io.FileInputStream;
19-
import java.io.FileNotFoundException;
20-
import java.io.FileOutputStream;
21-
import java.io.InputStream;
2216
import java.util.ArrayList;
2317
import java.util.Arrays;
24-
import java.util.Collection;
2518
import java.util.Collections;
2619
import java.util.HashMap;
2720
import java.util.Iterator;
2821
import java.util.LinkedHashMap;
2922
import java.util.List;
3023
import java.util.Map;
3124
import java.util.Map.Entry;
32-
import java.util.Objects;
33-
import java.util.Queue;
34-
import java.util.concurrent.ConcurrentLinkedQueue;
3525
import java.util.regex.Pattern;
3626
import java.util.stream.Collectors;
3727
import java.util.stream.Stream;
3828

3929
import org.eclipse.core.resources.IFile;
4030
import org.eclipse.core.resources.IProject;
4131
import org.eclipse.core.resources.IResource;
42-
import org.eclipse.core.resources.IResourceChangeEvent;
43-
import org.eclipse.core.resources.IResourceChangeListener;
44-
import org.eclipse.core.resources.ResourcesPlugin;
4532
import org.eclipse.core.runtime.CoreException;
4633
import org.eclipse.core.runtime.IPath;
47-
import org.eclipse.core.runtime.IProgressMonitor;
48-
import org.eclipse.core.runtime.IStatus;
49-
import org.eclipse.core.runtime.MultiStatus;
50-
import org.eclipse.core.runtime.Status;
51-
import org.eclipse.core.runtime.SubMonitor;
52-
import org.eclipse.core.runtime.jobs.Job;
5334
import org.eclipse.jdt.core.IClasspathAttribute;
5435
import org.eclipse.jdt.core.IClasspathContainer;
5536
import org.eclipse.jdt.core.IClasspathEntry;
@@ -69,10 +50,8 @@
6950
import org.eclipse.pde.core.plugin.IPluginLibrary;
7051
import org.eclipse.pde.core.plugin.IPluginModelBase;
7152
import org.eclipse.pde.internal.core.build.WorkspaceBuildModel;
72-
import org.eclipse.pde.internal.core.natures.PluginProject;
7353
import org.eclipse.pde.internal.core.project.PDEProject;
7454
import org.eclipse.pde.internal.core.util.CoreUtility;
75-
import org.eclipse.pde.internal.core.util.PDEClasspathContainerSaveHelper;
7655
import org.eclipse.team.core.RepositoryProvider;
7756

7857
public class ClasspathComputer {
@@ -87,26 +66,6 @@ private record ClasspathConfiguration(IPluginModelBase model, IJavaProject javaP
8766
private static final int SEVERITY_WARNING = 2;
8867
private static final int SEVERITY_IGNORE = 1;
8968

90-
/**
91-
* Job used to update class path containers.
92-
*/
93-
private static final UpdateClasspathsJob fUpdateJob = new UpdateClasspathsJob();
94-
95-
static final IResourceChangeListener CHANGE_LISTENER = new IResourceChangeListener() {
96-
97-
@Override
98-
public void resourceChanged(IResourceChangeEvent event) {
99-
IResource resource = event.getResource();
100-
if (resource instanceof IProject project) {
101-
if (PDECore.DEBUG_STATE) {
102-
PDECore.TRACE.trace(PDECore.KEY_DEBUG_STATE,
103-
String.format("Project %s was deleted.", project.getName())); //$NON-NLS-1$
104-
}
105-
getStateFile(project).delete();
106-
}
107-
}
108-
};
109-
11069
public static void setClasspath(IProject project, IPluginModelBase model) throws CoreException {
11170
IClasspathEntry[] entries = getClasspath(project, model, null, false, true);
11271
JavaCore.create(project).setRawClasspath(entries, null);
@@ -520,225 +479,4 @@ public static IClasspathEntry[] computeClasspathEntries(IPluginModelBase model,
520479
return container.getClasspathEntries();
521480
}
522481

523-
public static void requestClasspathUpdate(IProject project) {
524-
if (project == null) {
525-
return;
526-
}
527-
requestClasspathUpdate(List.of(project));
528-
}
529-
530-
public static void requestClasspathUpdate(Collection<IProject> updateProjects) {
531-
if (updateProjects == null || updateProjects.isEmpty()) {
532-
return;
533-
}
534-
fUpdateJob.addAll(updateProjects);
535-
}
536-
537-
static void requestClasspathUpdate(IProject project, IClasspathContainer savedState) {
538-
fUpdateJob.add(project, savedState);
539-
}
540-
541-
/**
542-
* Job to update class path containers asynchronously. Avoids blocking the
543-
* UI thread. The job is given a workspace lock so other jobs can't run on a
544-
* stale classpath.
545-
*/
546-
private static final class UpdateClasspathsJob extends Job {
547-
548-
private static final int WORK = 10_000;
549-
private final Queue<UpdateRequest> workQueue = new ConcurrentLinkedQueue<>();
550-
551-
/**
552-
* Constructs a new job.
553-
*/
554-
public UpdateClasspathsJob() {
555-
super(PDECoreMessages.PluginModelManager_1);
556-
// The job is given a workspace lock so other jobs can't run on a
557-
// stale classpath (bug 354993)
558-
setRule(ResourcesPlugin.getWorkspace().getRoot());
559-
}
560-
561-
@Override
562-
public boolean belongsTo(Object family) {
563-
return family == PluginModelManager.class || family == ClasspathComputer.class;
564-
}
565-
566-
@Override
567-
protected IStatus run(IProgressMonitor jobMonitor) {
568-
SubMonitor monitor = SubMonitor.convert(jobMonitor, PDECoreMessages.PluginModelManager_1, WORK);
569-
PluginModelManager.getInstance().initialize(monitor.split(10));
570-
PluginModelManager modelManager = PluginModelManager.getInstance();
571-
Map<IJavaProject, IClasspathContainer> updateProjects = new LinkedHashMap<>();
572-
Map<IProject, IStatus> errorsPerProject = new LinkedHashMap<>();
573-
UpdateRequest request;
574-
while (!monitor.isCanceled() && (request = workQueue.poll()) != null) {
575-
monitor.setWorkRemaining(WORK);
576-
IProject project = request.project();
577-
if (project.exists() && project.isOpen()) {
578-
IPluginModelBase model = modelManager.findModel(project);
579-
if (model != null && PluginProject.isJavaProject(project)) {
580-
IJavaProject javaProject = JavaCore.create(project);
581-
RequiredPluginsClasspathContainer classpathContainer = new RequiredPluginsClasspathContainer(
582-
model, project);
583-
try {
584-
if (!isUpToDate(project, classpathContainer.computeEntries(), request.container())) {
585-
updateProjects.put(javaProject, classpathContainer);
586-
errorsPerProject.remove(project);
587-
saveState(project, classpathContainer);
588-
}
589-
} catch (CoreException e) {
590-
errorsPerProject.put(project, e.getStatus());
591-
}
592-
monitor.worked(1);
593-
}
594-
}
595-
}
596-
if (monitor.isCanceled()) {
597-
return Status.CANCEL_STATUS;
598-
}
599-
if (!updateProjects.isEmpty()) {
600-
int i = 0;
601-
int n = updateProjects.size();
602-
IJavaProject[] javaProjects = new IJavaProject[n];
603-
IClasspathContainer[] container = new IClasspathContainer[n];
604-
for (Entry<IJavaProject, IClasspathContainer> entry : updateProjects.entrySet()) {
605-
javaProjects[i] = entry.getKey();
606-
container[i] = entry.getValue();
607-
i++;
608-
}
609-
try {
610-
setProjectContainers(javaProjects, container, monitor);
611-
} catch (JavaModelException e) {
612-
return e.getStatus();
613-
}
614-
}
615-
IStatus[] errors = errorsPerProject.values().toArray(IStatus[]::new);
616-
if (errors.length == 0) {
617-
return Status.OK_STATUS;
618-
}
619-
if (errors.length == 1) {
620-
return errors[0];
621-
}
622-
MultiStatus overallStatus = new MultiStatus(ClasspathComputer.class, 0,
623-
PDECoreMessages.ClasspathComputer_failed);
624-
for (IStatus status : errors) {
625-
overallStatus.add(status);
626-
}
627-
return overallStatus;
628-
}
629-
630-
/**
631-
* Queues more projects/containers.
632-
*/
633-
void addAll(Collection<IProject> tocheck) {
634-
for (IProject project : tocheck) {
635-
workQueue.add(new UpdateRequest(project, null));
636-
}
637-
schedule();
638-
}
639-
640-
void add(IProject project, IClasspathContainer classpathContainer) {
641-
if (project == null) {
642-
return;
643-
}
644-
workQueue.add(new UpdateRequest(project, classpathContainer));
645-
schedule();
646-
}
647-
648-
}
649-
650-
private static boolean isUpToDate(IProject project, IClasspathEntry[] currentEntries,
651-
IClasspathContainer previousClasspathContainer) {
652-
if (previousClasspathContainer == null) {
653-
if (PDECore.DEBUG_STATE) {
654-
PDECore.TRACE.trace(PDECore.KEY_DEBUG_STATE,
655-
String.format("%s need update because it has no state to compare", project.getName())); //$NON-NLS-1$
656-
}
657-
return false;
658-
}
659-
IClasspathEntry[] previousEntries = previousClasspathContainer.getClasspathEntries();
660-
if (previousEntries == null || previousEntries.length != currentEntries.length) {
661-
if (PDECore.DEBUG_STATE) {
662-
PDECore.TRACE.trace(PDECore.KEY_DEBUG_STATE,
663-
String.format("%s need update because entries do not match in size!", //$NON-NLS-1$
664-
project.getName()));
665-
}
666-
return false;
667-
}
668-
for (int i = 0; i < previousEntries.length; i++) {
669-
IClasspathEntry previous = previousEntries[i];
670-
IClasspathEntry current = currentEntries[i];
671-
if (!Objects.equals(current, previous)) {
672-
if (PDECore.DEBUG_STATE) {
673-
PDECore.TRACE.trace(PDECore.KEY_DEBUG_STATE,
674-
String.format("%s need update because entry at position %d is different:\n\t%s\n\t%s", //$NON-NLS-1$
675-
project.getName(), i, current, previous));
676-
}
677-
return false;
678-
}
679-
}
680-
return true;
681-
}
682-
683-
private static void saveState(IProject project, RequiredPluginsClasspathContainer classpathContainer) {
684-
synchronized (project) {
685-
try {
686-
File stateFile = getStateFile(project);
687-
stateFile.getParentFile().mkdirs();
688-
try (BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(stateFile))) {
689-
PDEClasspathContainerSaveHelper.writeContainer(classpathContainer, stream);
690-
}
691-
} catch (Exception e) {
692-
// can't write then...
693-
if (PDECore.DEBUG_STATE) {
694-
PDECore.TRACE.trace(PDECore.KEY_DEBUG_STATE,
695-
String.format("Writing project state for %s failed!", project.getName()), //$NON-NLS-1$
696-
e);
697-
}
698-
}
699-
}
700-
}
701-
702-
static IClasspathContainer readState(IProject project) {
703-
synchronized (project) {
704-
try {
705-
File stateFile = getStateFile(project);
706-
try (InputStream stream = new FileInputStream(stateFile)) {
707-
IClasspathContainer container = Objects
708-
.requireNonNull(PDEClasspathContainerSaveHelper.readContainer(stream));
709-
if (PDECore.DEBUG_STATE) {
710-
PDECore.TRACE.trace(PDECore.KEY_DEBUG_STATE,
711-
String.format("%s is restored from previous state.", project.getName())); //$NON-NLS-1$
712-
}
713-
return container;
714-
}
715-
} catch (Exception e) {
716-
if (PDECore.DEBUG_STATE) {
717-
if (e instanceof FileNotFoundException) {
718-
PDECore.TRACE.trace(PDECore.KEY_DEBUG_STATE,
719-
String.format("%s has no saved state!", project.getName())); //$NON-NLS-1$
720-
} else {
721-
PDECore.TRACE.trace(PDECore.KEY_DEBUG_STATE,
722-
String.format("Restoring project state for %s failed!", project.getName()), e); //$NON-NLS-1$
723-
}
724-
}
725-
return PDEClasspathContainerSaveHelper.emptyContainer();
726-
}
727-
}
728-
}
729-
730-
static void setProjectContainers(IJavaProject[] javaProjects, IClasspathContainer[] container,
731-
IProgressMonitor monitor) throws JavaModelException {
732-
JavaCore.setClasspathContainer(PDECore.REQUIRED_PLUGINS_CONTAINER_PATH, javaProjects, container, monitor);
733-
}
734-
735-
private static File getStateFile(IProject project) {
736-
return PDECore.getDefault().getStateLocation().append("cpc").append(project.getName()) //$NON-NLS-1$
737-
.toFile();
738-
}
739-
740-
private static record UpdateRequest(IProject project, IClasspathContainer container) {
741-
742-
}
743-
744482
}

0 commit comments

Comments
 (0)