Skip to content

Commit 808ea59

Browse files
committed
Migrating tasks to use BgTask
1 parent 85cda09 commit 808ea59

31 files changed

+365
-463
lines changed
Lines changed: 70 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,41 @@
11
package fi.helsinki.cs.tmc.actions;
22

3-
import com.google.common.util.concurrent.FutureCallback;
4-
import com.google.common.util.concurrent.Futures;
5-
import com.google.common.util.concurrent.ListenableFuture;
3+
import static java.util.logging.Level.INFO;
4+
65
import fi.helsinki.cs.tmc.core.domain.Course;
76
import fi.helsinki.cs.tmc.model.CourseDb;
87
import fi.helsinki.cs.tmc.model.LocalExerciseStatus;
98
import fi.helsinki.cs.tmc.model.ObsoleteClientException;
10-
import fi.helsinki.cs.tmc.model.NBTmcSettings;
11-
import fi.helsinki.cs.tmc.model.ServerAccess;
9+
import fi.helsinki.cs.tmc.model.NbTmcSettings;
1210
import fi.helsinki.cs.tmc.model.TmcCoreSingleton;
1311
import fi.helsinki.cs.tmc.ui.DownloadOrUpdateExercisesDialog;
1412
import fi.helsinki.cs.tmc.ui.ConvenientDialogDisplayer;
1513
import fi.helsinki.cs.tmc.ui.TmcNotificationDisplayer;
1614
import fi.helsinki.cs.tmc.utilities.Inflector;
1715
import fi.helsinki.cs.tmc.utilities.TmcStringUtils;
1816
import fi.helsinki.cs.tmc.core.TmcCore;
19-
import fi.helsinki.cs.tmc.core.domain.Exercise;
20-
import fi.helsinki.cs.tmc.core.exceptions.TmcCoreException;
21-
import java.awt.event.ActionEvent;
22-
import java.awt.event.ActionListener;
23-
import java.net.URI;
24-
import java.util.ArrayList;
25-
import javax.swing.AbstractAction;
26-
import javax.swing.Icon;
27-
import javax.swing.SwingUtilities;
17+
import fi.helsinki.cs.tmc.utilities.BgTask;
18+
import fi.helsinki.cs.tmc.utilities.BgTaskListener;
19+
import fi.helsinki.cs.tmc.utilities.CancellableCallable;
20+
21+
import com.google.common.util.concurrent.ListenableFuture;
22+
2823
import org.apache.commons.lang3.StringUtils;
29-
import org.netbeans.api.progress.ProgressHandle;
30-
import org.netbeans.api.progress.ProgressHandleFactory;
24+
3125
import org.openide.awt.ActionID;
3226
import org.openide.awt.ActionReference;
3327
import org.openide.awt.ActionReferences;
3428
import org.openide.awt.ActionRegistration;
35-
import org.openide.util.Exceptions;
3629
import org.openide.util.ImageUtilities;
3730
import org.openide.util.NbBundle.Messages;
3831

32+
import java.util.logging.Logger;
33+
import java.awt.event.ActionEvent;
34+
import java.awt.event.ActionListener;
35+
import java.util.ArrayList;
36+
import javax.swing.AbstractAction;
37+
import javax.swing.Icon;
38+
3939
@ActionID(category = "TMC",
4040
id = "fi.helsinki.cs.tmc.actions.CheckForNewExercisesOrUpdates")
4141
@ActionRegistration(displayName = "#CTL_CheckForNewExercisesOrUpdates")
@@ -52,14 +52,16 @@ public static void startTimer() {
5252
timer.start();
5353
}
5454

55+
private static final Logger logger = Logger.getLogger(CheckForNewExercisesOrUpdates.class.getName());
56+
5557
private static final TmcNotificationDisplayer.SingletonToken notifierToken = TmcNotificationDisplayer.createSingletonToken();
5658

5759
private CourseDb courseDb;
5860
private TmcNotificationDisplayer notifier;
5961
private ConvenientDialogDisplayer dialogs;
6062
private boolean beQuiet;
6163
private boolean backgroundCheck;
62-
private TmcCore tmcCore;
64+
private final TmcCore tmcCore;
6365

6466
public CheckForNewExercisesOrUpdates() {
6567
this(false, false);
@@ -76,118 +78,80 @@ public CheckForNewExercisesOrUpdates(boolean beQuiet, boolean backgroundCheck) {
7678

7779
@Override
7880
public void actionPerformed(ActionEvent e) {
81+
logger.info("action performed");
7982
run();
8083
}
8184

8285
public void run() {
83-
try {
84-
final Course currentCourseBeforeUpdate = courseDb.getCurrentCourse();
85-
if (backgroundProcessingOrNoCurrentCourse(currentCourseBeforeUpdate)) {
86-
return;
87-
}
88-
ProgressHandle exerciseRefresh = ProgressHandleFactory.createSystemHandle(
89-
"Checking for new exercises");
90-
exerciseRefresh.start();
91-
ListenableFuture<Course> currentCourseFuture = this.tmcCore.getCourse(
92-
detailUrl(currentCourseBeforeUpdate)
93-
);
94-
Futures.addCallback(currentCourseFuture, new UpdateCourseForExerciseUpdate(exerciseRefresh));
95-
} catch (TmcCoreException ex) {
96-
Exceptions.printStackTrace(ex);
97-
}
98-
}
86+
final Course currentCourseBeforeUpdate = courseDb.getCurrentCourse();
9987

100-
private URI detailUrl(final Course currentCourseBeforeUpdate) {
101-
return URI.create(new ServerAccess().addApiCallQueryParameters(
102-
currentCourseBeforeUpdate.getDetailsUrl()));
103-
}
104-
105-
/**
106-
* If there is something at background or no current course is chosen,
107-
* return true.
108-
*/
109-
private boolean backgroundProcessingOrNoCurrentCourse(final Course currentCourseBeforeUpdate) {
110-
if (backgroundCheck && !NBTmcSettings.getDefault().isCheckingForUpdatesInTheBackground()) {
111-
return true;
88+
if (backgroundCheck && !NbTmcSettings.getDefault().isCheckingForUpdatesInTheBackground()) {
89+
return;
11290
}
91+
11392
if (currentCourseBeforeUpdate == null) {
11493
if (!beQuiet) {
11594
dialogs.displayMessage("Please select a course in TMC -> Settings.");
11695
}
117-
return true;
96+
return;
11897
}
119-
return false;
120-
}
12198

122-
class UpdateCourseForExerciseUpdate implements FutureCallback<Course> {
99+
BgTaskListener bgTaskListener = new BgTaskListener<Course>() {
100+
@Override
101+
public void bgTaskReady(Course receivedCourse) {
102+
if (receivedCourse != null) {
123103

124-
private ProgressHandle lastAction;
104+
courseDb.putDetailedCourse(receivedCourse);
125105

126-
/**
127-
* This should be attached to listenableFuture. When future is ready,
128-
* receivedCourse will be saved to courseDb and view will be updated.
129-
*/
130-
public UpdateCourseForExerciseUpdate(ProgressHandle lastAction) {
131-
this.lastAction = lastAction;
132-
}
106+
final LocalExerciseStatus status = LocalExerciseStatus.get(receivedCourse.getExercises());
133107

134-
@Override
135-
public void onSuccess(final Course receivedCourse) {
136-
SwingUtilities.invokeLater(new Runnable() {
137-
138-
@Override
139-
public void run() {
140-
lastAction.finish();
141-
if (receivedCourse != null) {
142-
setCourseNameToAllExercises(receivedCourse);
143-
courseDb.putDetailedCourse(receivedCourse);
144-
final LocalExerciseStatus status = LocalExerciseStatus.get(receivedCourse.getExercises());
145-
updateGUI(status);
108+
if (status.thereIsSomethingToDownload(false)) {
109+
if (beQuiet) {
110+
displayNotification(status, new ActionListener() {
111+
@Override
112+
public void actionPerformed(ActionEvent e) {
113+
DownloadOrUpdateExercisesDialog.display(status.unlockable, status.downloadableUncompleted, status.updateable);
114+
}
115+
});
116+
} else {
117+
DownloadOrUpdateExercisesDialog.display(status.unlockable, status.downloadableUncompleted, status.updateable);
118+
}
119+
} else if (!beQuiet) {
120+
dialogs.displayMessage("No new exercises or updates to download.");
146121
}
147122
}
123+
}
148124

149-
});
150-
151-
}
152-
153-
private void setCourseNameToAllExercises(Course receivedCourse) {
154-
for (Exercise exercise : receivedCourse.getExercises()) {
155-
exercise.setCourseName(receivedCourse.getName());
125+
@Override
126+
public void bgTaskCancelled() {
156127
}
157-
}
158128

159-
private void updateGUI(final LocalExerciseStatus status) {
160-
boolean thereIsSomethingToDownload = status.thereIsSomethingToDownload(false);
161-
if (thereIsSomethingToDownload) {
162-
if (beQuiet) {
163-
displayNotification(status, new ActionListener() {
164-
@Override
165-
public void actionPerformed(ActionEvent e) {
166-
DownloadOrUpdateExercisesDialog.display(status.unlockable, status.downloadableUncompleted, status.updateable);
167-
}
168-
});
169-
} else {
170-
DownloadOrUpdateExercisesDialog.display(status.unlockable, status.downloadableUncompleted, status.updateable);
129+
@Override
130+
public void bgTaskFailed(Throwable ex) {
131+
if (!beQuiet || ex instanceof ObsoleteClientException) {
132+
dialogs.displayError("Failed to check for new exercises.\n" + ServerErrorHelper.getServerExceptionMsg(ex));
171133
}
172-
} else if (!beQuiet) {
173-
dialogs.displayMessage("No new exercises or updates to download.");
174134
}
175-
}
135+
};
176136

177-
@Override
178-
public void onFailure(final Throwable ex) {
179-
SwingUtilities.invokeLater(new Runnable() {
137+
BgTask.start("Checking for new exercises", new CancellableCallable<Course>() {
138+
ListenableFuture<Course> currentCourseFuture;
180139

181-
@Override
182-
public void run() {
183-
lastAction.finish();
184-
if (!beQuiet || ex instanceof ObsoleteClientException) {
185-
dialogs.displayError("Failed to check for new exercises.\n" + ServerErrorHelper.getServerExceptionMsg(ex));
186-
}
187-
}
140+
@Override
141+
public Course call() throws Exception {
142+
logger.info("1Downloading course to refresh cache");
143+
144+
currentCourseFuture = tmcCore.getCourse(currentCourseBeforeUpdate.getDetailsUrlAsUri());
145+
return currentCourseFuture.get();
146+
}
147+
148+
@Override
149+
public boolean cancel() {
150+
logger.log(INFO, "Get course (refresh list) cancelled.");
151+
return currentCourseFuture.cancel(true);
152+
}
153+
}, bgTaskListener);
188154

189-
});
190-
}
191155
}
192156

193157
private void displayNotification(LocalExerciseStatus status, ActionListener action) {
@@ -224,4 +188,4 @@ private void displayNotification(LocalExerciseStatus status, ActionListener acti
224188
private Icon getNotificationIcon() {
225189
return ImageUtilities.loadImageIcon("fi/helsinki/cs/tmc/smile.gif", false);
226190
}
227-
}
191+
}

tmc-plugin/src/fi/helsinki/cs/tmc/actions/CheckForNewReviews.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import fi.helsinki.cs.tmc.core.domain.Course;
77
import fi.helsinki.cs.tmc.core.domain.Review;
88
import fi.helsinki.cs.tmc.model.CourseDb;
9-
import fi.helsinki.cs.tmc.model.NBTmcSettings;
9+
import fi.helsinki.cs.tmc.model.NbTmcSettings;
1010
import fi.helsinki.cs.tmc.model.ReviewDb;
1111
import fi.helsinki.cs.tmc.model.TmcCoreSingleton;
1212
import fi.helsinki.cs.tmc.ui.ConvenientDialogDisplayer;
@@ -79,6 +79,7 @@ public void actionPerformed(ActionEvent e) {
7979

8080
@Override
8181
public void run() {
82+
// TODO(jamo): use bg task
8283
if (resetNotifications) {
8384
reviewDb.forgetReviewsNotifiedAbout();
8485
}

tmc-plugin/src/fi/helsinki/cs/tmc/actions/CheckForUnopenedExercises.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import fi.helsinki.cs.tmc.model.CourseDb;
55
import fi.helsinki.cs.tmc.model.ProjectMediator;
66
import fi.helsinki.cs.tmc.model.TmcProjectInfo;
7-
import fi.helsinki.cs.tmc.model.NBTmcSettings;
7+
import fi.helsinki.cs.tmc.model.NbTmcSettings;
88
import fi.helsinki.cs.tmc.ui.TmcNotificationDisplayer;
99
import java.awt.event.ActionEvent;
1010
import java.awt.event.ActionListener;
@@ -16,7 +16,7 @@
1616

1717
public class CheckForUnopenedExercises implements ActionListener {
1818
public static boolean shouldRunOnStartup() {
19-
return NBTmcSettings.getDefault().isCheckingForUnopenedAtStartup();
19+
return NbTmcSettings.getDefault().isCheckingForUnopenedAtStartup();
2020
}
2121

2222
private static final TmcNotificationDisplayer.SingletonToken notifierToken = TmcNotificationDisplayer.createSingletonToken();
@@ -37,6 +37,7 @@ public void actionPerformed(ActionEvent e) {
3737
}
3838

3939
public void run() {
40+
// TODO(jamo): use bg task
4041
projects.callWhenProjectsCompletelyOpened(new Runnable() {
4142
@Override
4243
public void run() {

tmc-plugin/src/fi/helsinki/cs/tmc/actions/DownloadCompletedExercises.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ public DownloadCompletedExercises() {
4040

4141
@Override
4242
public void actionPerformed(ActionEvent e) {
43+
// TODO(jamo): use bg task
4344
final Course currentCourse = courseDb.getCurrentCourse();
4445
if (currentCourse == null) {
4546
dialogs.displayMessage("Please select a course in TMC -> Settings.");
@@ -48,10 +49,10 @@ public void actionPerformed(ActionEvent e) {
4849

4950
RefreshCoursesAction action = new RefreshCoursesAction();
5051
action.addDefaultListener(true, true);
51-
action.addListener(new FutureCallback<List<Course>>() {
52+
action.addListener(new BgTaskListener<List<Course>>() {
5253

5354
@Override
54-
public void onSuccess(List<Course> receivedCourseList) {
55+
public void bgTaskReady(List<Course> result) {
5556
LocalExerciseStatus status = LocalExerciseStatus.get(courseDb.getCurrentCourseExercises());
5657
if (!status.downloadableCompleted.isEmpty()) {
5758
List<Exercise> emptyList = Collections.emptyList();
@@ -62,10 +63,14 @@ public void onSuccess(List<Course> receivedCourseList) {
6263
}
6364

6465
@Override
65-
public void onFailure(Throwable ex) {
66+
public void bgTaskCancelled() {
67+
}
68+
69+
@Override
70+
public void bgTaskFailed(Throwable ex) {
6671
dialogs.displayError("Failed to check for new exercises.\n" + ServerErrorHelper.getServerExceptionMsg(ex));
6772
}
6873
});
6974
action.run();
7075
}
71-
}
76+
}

0 commit comments

Comments
 (0)