1 package de.spiritscorp.datasync.model;
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.Files;
24 import java.nio.file.Path;
25 import java.util.ArrayList;
26 import java.util.Map;
27
28 import de.spiritscorp.datasync.ScanType;
29 import de.spiritscorp.datasync.io.Debug;
30 import de.spiritscorp.datasync.io.Logger;
31 import de.spiritscorp.datasync.io.Preference;
32
33 public class BgModel {
34
35 private final Preference pref;
36 private final FileHandler handler;
37 private final Map<Path, FileAttributes> sourceMap, destMap;
38
39 public BgModel( Preference pref, Logger logger, Map<Path, FileAttributes> sourceMap, Map<Path, FileAttributes> destMap ) {
40 this.pref = pref;
41 this.sourceMap = sourceMap;
42 this.destMap = destMap;
43 handler = new FileHandler( logger );
44 }
45
46
47
48
49
50
51
52 public boolean runBgJob() {
53 final boolean logOn = pref.isLogOn();
54 final Map<Path, FileAttributes> syncMap = pref.getSyncMap();
55 final Path startSourcePath = pref.getStartSourcePath();
56 final Path startDestPath = pref.getStartDestPath();
57 final Path trashbinPath = pref.getTrashbinPath();
58 final boolean trashbin = pref.isTrashbin();
59 final boolean autoBgDel = pref.isAutoBgDel();
60 final ScanType scanType = pref.getScanMode();
61
62 Debug.printDebug( "[BgModel] Time since last scan: %s", formatDuration( System.currentTimeMillis() - pref.getLastScanTime() ) );
63 if( scanType == ScanType.SYNCHRONIZE ) {
64 if( Files.exists( pref.getStartDestPath() ) ) {
65 if( System.currentTimeMillis() - pref.getLastScanTime() > pref.getBgTime().getTime() ) {
66 Debug.printDebug( "[BgModel] BgJob running" );
67 Debug.printDebug( "[BgModel] List start" );
68 final Thread t1 = new Thread( () -> handler.listFiles( pref.getSourcePath(), sourceMap, scanType, false ) );
69 final Thread t2 = new Thread( () -> handler.listFiles( pref.getDestPath(), destMap, scanType, false ) );
70 t1.start();
71 t2.start();
72 try {
73 t1.join();
74 t2.join();
75 }catch( final InterruptedException e ) {
76 Debug.printException( this.getClass(), e );
77 }
78 Debug.printDebug( "[BgModel] List ready" );
79 Debug.printDebug( "[BgModel] SourceMap size -> %s | DestMap size -> %s", sourceMap.size(), destMap.size() );
80 Debug.printDebug( "[BgModel] Synchronization start" );
81
82
83
84
85
86
87
88 final ArrayList<Map<Path, FileAttributes>> result = handler.getSyncFiles( sourceMap, destMap, startSourcePath, startDestPath, syncMap );
89 Debug.printDebug( "[BgModel] Synchronization list ready" );
90
91 Debug.printDebug( "[BgModel] Process files start" );
92 if( !result.get( 0 ).isEmpty() ) handler.copyFiles( result.get( 0 ), false, startDestPath );
93 if( !result.get( 1 ).isEmpty() ) handler.copyFiles( result.get( 1 ), false, startSourcePath );
94 if( !result.get( 2 ).isEmpty() ) handler.deleteFiles( result.get( 2 ), false, false, null );
95
96 sourceMap.clear();
97 destMap.clear();
98 syncMap.clear();
99
100 final Map<Path, FileAttributes> tempMap = Model.createMap();
101 handler.listFiles( pref.getSourcePath(), tempMap, scanType, false );
102 for( final Map.Entry<Path, FileAttributes> entry : tempMap.entrySet() ) {
103 syncMap.put( entry.getValue().getRelativeFilePath(), entry.getValue() );
104 }
105 pref.writeSyncMap();
106 pref.saveLastScanTime();
107 Debug.printDebug( "[BgModel] Files successfully processed" );
108 Debug.printDebug( "[BgModel] BgJob finish" );
109 return result.get( 0 ).isEmpty() && result.get( 1 ).isEmpty() && result.get( 2 ).isEmpty();
110 }
111 }
112 }else if( scanType == ScanType.DEEP_SCAN || scanType == ScanType.FLAT_SCAN ) {
113 if( Files.exists( pref.getStartDestPath() ) ) {
114 if( System.currentTimeMillis() - pref.getLastScanTime() > pref.getBgTime().getTime() ) {
115 Debug.printDebug( "[BgModel] BgJob running" );
116 Debug.printDebug( "[BgModel] List start" );
117 final Thread t1 = new Thread( () -> handler.listFiles( pref.getSourcePath(), sourceMap, scanType, pref.isSubDir() ) );
118 final Thread t2 = new Thread( () -> handler.listFiles( pref.getDestPath(), destMap, scanType, pref.isSubDir() ) );
119 t1.start();
120 t2.start();
121 try {
122 t1.join();
123 t2.join();
124 }catch( final InterruptedException e ) {
125 Debug.printException( this.getClass(), e );
126 }
127 Debug.printDebug( "[BgModel] List ready" );
128 Debug.printDebug( "[BgModel] SourceMap size -> %s | DestMap size -> %s", sourceMap.size(), destMap.size() );
129
130 Debug.printDebug( "[BgModel] Equals Files start" );
131 handler.equalsFiles( sourceMap, destMap );
132 Debug.printDebug( "[BgModel] Equals Files ready" );
133
134 Debug.printDebug( "[BgModel] Process files start" );
135 if( autoBgDel && !destMap.isEmpty() ) handler.deleteFiles( destMap, logOn, trashbin, trashbinPath );
136 if( !sourceMap.isEmpty() ) handler.copyFiles( sourceMap, logOn, startDestPath );
137 pref.saveLastScanTime();
138 Debug.printDebug( "[BgModel] Files successfully processed" );
139 Debug.printDebug( "[BgModel] BgJob finish" );
140 return sourceMap.isEmpty() && destMap.isEmpty();
141 }
142 }
143 }else {
144 Debug.printDebug( "[BgModel] No valid background job" );
145 }
146 return false;
147 }
148
149
150
151
152
153
154
155 private static String formatDuration( final long durationMs ) {
156 if( durationMs < 1000 ) { return durationMs + "ms"; }
157
158 final long totalSeconds = durationMs / 1_000;
159 final long seconds = totalSeconds % 60;
160 final long totalMinutes = totalSeconds / 60;
161 final long minutes = totalMinutes % 60;
162 final long totalHours = totalMinutes / 60;
163 final long hours = totalHours % 24;
164 final long days = totalHours / 24;
165
166 final StringBuilder builder = new StringBuilder();
167
168 if( days > 0 ) {
169 builder.append( days ).append( "d " );
170 }
171 if( hours > 0 ) {
172 builder.append( hours ).append( "h " );
173 }
174 if( minutes > 0 ) {
175 builder.append( minutes ).append( "m " );
176 }
177
178 if( seconds > 0 || builder.isEmpty() ) {
179 builder.append( seconds ).append( 's' );
180 }
181
182 return builder.toString().trim();
183 }
184 }