1
1
package fi .helsinki .cs .tmc .actions ;
2
2
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
+
6
5
import fi .helsinki .cs .tmc .core .domain .Course ;
7
6
import fi .helsinki .cs .tmc .model .CourseDb ;
8
7
import fi .helsinki .cs .tmc .model .LocalExerciseStatus ;
9
8
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 ;
12
10
import fi .helsinki .cs .tmc .model .TmcCoreSingleton ;
13
11
import fi .helsinki .cs .tmc .ui .DownloadOrUpdateExercisesDialog ;
14
12
import fi .helsinki .cs .tmc .ui .ConvenientDialogDisplayer ;
15
13
import fi .helsinki .cs .tmc .ui .TmcNotificationDisplayer ;
16
14
import fi .helsinki .cs .tmc .utilities .Inflector ;
17
15
import fi .helsinki .cs .tmc .utilities .TmcStringUtils ;
18
16
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
+
28
23
import org .apache .commons .lang3 .StringUtils ;
29
- import org .netbeans .api .progress .ProgressHandle ;
30
- import org .netbeans .api .progress .ProgressHandleFactory ;
24
+
31
25
import org .openide .awt .ActionID ;
32
26
import org .openide .awt .ActionReference ;
33
27
import org .openide .awt .ActionReferences ;
34
28
import org .openide .awt .ActionRegistration ;
35
- import org .openide .util .Exceptions ;
36
29
import org .openide .util .ImageUtilities ;
37
30
import org .openide .util .NbBundle .Messages ;
38
31
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
+
39
39
@ ActionID (category = "TMC" ,
40
40
id = "fi.helsinki.cs.tmc.actions.CheckForNewExercisesOrUpdates" )
41
41
@ ActionRegistration (displayName = "#CTL_CheckForNewExercisesOrUpdates" )
@@ -52,14 +52,16 @@ public static void startTimer() {
52
52
timer .start ();
53
53
}
54
54
55
+ private static final Logger logger = Logger .getLogger (CheckForNewExercisesOrUpdates .class .getName ());
56
+
55
57
private static final TmcNotificationDisplayer .SingletonToken notifierToken = TmcNotificationDisplayer .createSingletonToken ();
56
58
57
59
private CourseDb courseDb ;
58
60
private TmcNotificationDisplayer notifier ;
59
61
private ConvenientDialogDisplayer dialogs ;
60
62
private boolean beQuiet ;
61
63
private boolean backgroundCheck ;
62
- private TmcCore tmcCore ;
64
+ private final TmcCore tmcCore ;
63
65
64
66
public CheckForNewExercisesOrUpdates () {
65
67
this (false , false );
@@ -76,118 +78,80 @@ public CheckForNewExercisesOrUpdates(boolean beQuiet, boolean backgroundCheck) {
76
78
77
79
@ Override
78
80
public void actionPerformed (ActionEvent e ) {
81
+ logger .info ("action performed" );
79
82
run ();
80
83
}
81
84
82
85
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 ();
99
87
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 ;
112
90
}
91
+
113
92
if (currentCourseBeforeUpdate == null ) {
114
93
if (!beQuiet ) {
115
94
dialogs .displayMessage ("Please select a course in TMC -> Settings." );
116
95
}
117
- return true ;
96
+ return ;
118
97
}
119
- return false ;
120
- }
121
98
122
- class UpdateCourseForExerciseUpdate implements FutureCallback <Course > {
99
+ BgTaskListener bgTaskListener = new BgTaskListener <Course >() {
100
+ @ Override
101
+ public void bgTaskReady (Course receivedCourse ) {
102
+ if (receivedCourse != null ) {
123
103
124
- private ProgressHandle lastAction ;
104
+ courseDb . putDetailedCourse ( receivedCourse ) ;
125
105
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 ());
133
107
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." );
146
121
}
147
122
}
123
+ }
148
124
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 () {
156
127
}
157
- }
158
128
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 ));
171
133
}
172
- } else if (!beQuiet ) {
173
- dialogs .displayMessage ("No new exercises or updates to download." );
174
134
}
175
- }
135
+ };
176
136
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 ;
180
139
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 );
188
154
189
- });
190
- }
191
155
}
192
156
193
157
private void displayNotification (LocalExerciseStatus status , ActionListener action ) {
@@ -224,4 +188,4 @@ private void displayNotification(LocalExerciseStatus status, ActionListener acti
224
188
private Icon getNotificationIcon () {
225
189
return ImageUtilities .loadImageIcon ("fi/helsinki/cs/tmc/smile.gif" , false );
226
190
}
227
- }
191
+ }
0 commit comments