1 package de.spiritscorp.datasync.controller;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 import java.nio.file.Path;
24
25 import de.spiritscorp.datasync.ScanType;
26 import de.spiritscorp.datasync.io.Debug;
27 import de.spiritscorp.datasync.io.Preference;
28 import de.spiritscorp.datasync.io.PreferenceManager;
29 import de.spiritscorp.datasync.model.FileAttributes;
30 import javafx.application.Platform;
31 import javafx.beans.property.BooleanProperty;
32 import javafx.beans.property.SimpleBooleanProperty;
33 import javafx.beans.property.SimpleStringProperty;
34 import javafx.beans.property.StringProperty;
35 import javafx.collections.FXCollections;
36 import javafx.collections.ObservableList;
37
38
39
40
41
42
43 public class SyncJobContext {
44
45 private final StringProperty jobName = new SimpleStringProperty();
46 private final BooleanProperty running = new SimpleBooleanProperty( false );
47 private final StringProperty statusMessage = new SimpleStringProperty( "Bereit" );
48 private final StringProperty logOutput = new SimpleStringProperty( "" );
49 private final StringProperty selectedMode = new SimpleStringProperty( ScanType.SYNCHRONIZE.getDescription() );
50
51 private final Preference taskPreference;
52 private Thread activeWorkerThread;
53
54 private final ObservableList<FileRow> duplicateFiles = FXCollections.observableArrayList();
55
56
57
58
59
60
61
62 public SyncJobContext( String name, Preference taskPreference ) {
63 this.jobName.set( name );
64 this.taskPreference = taskPreference;
65 }
66
67
68
69
70
71 synchronized void setActiveWorkerThread( Thread thread ) { this.activeWorkerThread = thread; }
72
73
74
75
76
77
78
79
80 public synchronized void cancelRunningTask( long timeoutMs ) {
81 if( activeWorkerThread != null && activeWorkerThread.isAlive() ) {
82 Debug.printDebug( "[Info] Sending interruption signal to worker thread for job: %s", getJobName() );
83 activeWorkerThread.interrupt();
84
85 if( timeoutMs > 0 ) {
86 try {
87
88 activeWorkerThread.join( timeoutMs );
89 if( activeWorkerThread.isAlive() ) {
90 Debug.printDebug( "[Warn] Warning: Worker thread for job '%s' breached timeout matrix.", getJobName() );
91 }
92 }catch( final InterruptedException e ) {
93 Debug.printDebug( "[Info] Thread joining sequence was interrupted for job: %s", getJobName() );
94 Thread.currentThread().interrupt();
95 }
96 }
97
98
99 if( !activeWorkerThread.isAlive() ) {
100 setRunning( false );
101 setStatusMessage( "Aktion erfolgreich beendet." );
102 appendLog( "-> Vorgang sauber beendet." );
103 }else {
104 setRunning( false );
105 setStatusMessage( "Aktion vom Benutzer abgebrochen (Forced)." );
106 appendLog( "-> Vorgang erzwungen abgebrochen." );
107 }
108 }else {
109 updateUIAndLog( "Keine aktive Aktion.", "-> Nichts zu beenden gefunden." );
110 }
111 }
112
113
114
115
116 private void updateUIAndLog( String status, String logEntry ) {
117 if( Platform.isFxApplicationThread() ) {
118 setStatusMessage( status );
119 appendLog( logEntry );
120 }else {
121 try {
122 Platform.runLater( () -> {
123 setStatusMessage( status );
124 appendLog( logEntry );
125 } );
126 }catch( final IllegalStateException e ) {
127
128
129 Debug.printDebug( "[Info] GUI framework offline. Suppressed state update: %s (%s)", status, logEntry );
130 }
131 }
132 }
133
134 public void appendLog( String line ) {
135 this.logOutput.set( this.logOutput.get() + line + System.lineSeparator() );
136 }
137
138 void clearLog() {
139 this.logOutput.set( "" );
140 }
141
142 public String getJobName() { return jobName.get(); }
143
144 public StringProperty jobNameProperty() {
145 return jobName;
146 }
147
148 public boolean isRunning() { return running.get(); }
149
150 public BooleanProperty runningProperty() {
151 return running;
152 }
153
154 void setRunning( boolean value ) {
155 this.running.set( value );
156 }
157
158 public String getStatusMessage() { return statusMessage.get(); }
159
160 public StringProperty statusMessageProperty() {
161 return statusMessage;
162 }
163
164 public void setStatusMessage( String message ) {
165 this.statusMessage.set( message );
166 }
167
168 public String getLogOutput() { return logOutput.get(); }
169
170 public StringProperty logOutputProperty() {
171 return logOutput;
172 }
173
174 public ScanType getSelectedMode() { return ScanType.get( selectedMode.get() ); }
175
176 public StringProperty selectedModeProperty() {
177 return selectedMode;
178 }
179
180 public void setSelectedMode( String mode ) {
181 this.selectedMode.set( mode );
182 }
183
184 public Preference getPreference() { return taskPreference; }
185
186 public ObservableList<FileRow> getDuplicateFiles() { return duplicateFiles; }
187
188
189
190
191 public static class FileRow {
192 private final BooleanProperty selected = new SimpleBooleanProperty( false );
193 private final StringProperty fileName = new SimpleStringProperty();
194 private final StringProperty size = new SimpleStringProperty();
195 private final StringProperty hash = new SimpleStringProperty();
196 private final StringProperty path = new SimpleStringProperty();
197 private final Path fileSystemPath;
198
199 public FileRow( Path path, FileAttributes attr, String readableSize ) {
200 this.fileSystemPath = path;
201 this.fileName.set( attr.getFileName() );
202 this.size.set( readableSize );
203 this.hash.set( attr.getFileHash() );
204 this.path.set( path.toString() );
205 }
206
207 public BooleanProperty selectedProperty() {
208 return selected;
209 }
210
211 public boolean isSelected() { return selected.get(); }
212
213 public void setSelected( boolean val ) {
214 this.selected.set( val );
215 }
216
217 public StringProperty fileNameProperty() {
218 return fileName;
219 }
220
221 public StringProperty sizeProperty() {
222 return size;
223 }
224
225 public StringProperty hashProperty() {
226 return hash;
227 }
228
229 public StringProperty pathProperty() {
230 return path;
231 }
232
233 public Path getFileSystemPath() { return fileSystemPath; }
234 }
235
236 void setJobName( String newTaskName ) {
237 PreferenceManager.getInstance().renameProfile( jobName.get(), newTaskName, this.getPreference() );
238 this.jobName.set( newTaskName );
239 }
240 }