11package 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+
65import fi .helsinki .cs .tmc .core .domain .Course ;
76import fi .helsinki .cs .tmc .model .CourseDb ;
87import fi .helsinki .cs .tmc .model .LocalExerciseStatus ;
98import 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 ;
1210import fi .helsinki .cs .tmc .model .TmcCoreSingleton ;
1311import fi .helsinki .cs .tmc .ui .DownloadOrUpdateExercisesDialog ;
1412import fi .helsinki .cs .tmc .ui .ConvenientDialogDisplayer ;
1513import fi .helsinki .cs .tmc .ui .TmcNotificationDisplayer ;
1614import fi .helsinki .cs .tmc .utilities .Inflector ;
1715import fi .helsinki .cs .tmc .utilities .TmcStringUtils ;
1816import 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+
2823import org .apache .commons .lang3 .StringUtils ;
29- import org .netbeans .api .progress .ProgressHandle ;
30- import org .netbeans .api .progress .ProgressHandleFactory ;
24+
3125import org .openide .awt .ActionID ;
3226import org .openide .awt .ActionReference ;
3327import org .openide .awt .ActionReferences ;
3428import org .openide .awt .ActionRegistration ;
35- import org .openide .util .Exceptions ;
3629import org .openide .util .ImageUtilities ;
3730import 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+ }
0 commit comments