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