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 import java.util.Map;
25
26 import de.spiritscorp.datasync.ScanType;
27 import de.spiritscorp.datasync.model.FileAttributes;
28
29
30
31
32
33
34
35
36
37
38
39
40 @SuppressWarnings( "PMD.LongVariable" )
41 public class UiLogFormatter {
42
43
44
45 private static final long BYTES_PER_GIB_THRESHOLD = 1_073_741_824L;
46
47 private static final long BYTES_PER_MIB_THRESHOLD = 1_048_576L;
48
49 private static final long BYTES_PER_KIB_THRESHOLD = 1_024L;
50
51 private static final double CONVERSION_FACTOR_MIB = 1_048_576.0;
52
53 private static final double CONVERSION_FACTOR_KIB = 1_024.0;
54
55 private static final long MINIMUM_BYTE_PLURAL_THRESHOLD = 1L;
56
57
58
59 private static final double NANOSECONDS_PER_SECOND = 1_000_000_000.0;
60
61 private static final int SECONDS_PER_TWO_HOURS = 7200;
62
63 private static final int SECONDS_PER_ONE_HOUR = 3600;
64
65 private static final int SECONDS_PER_MINUTE = 60;
66
67
68
69 private static final int DEFAULT_LOG_DISPLAY_LIMIT = 10_000;
70
71 private static final int INITIAL_LOG_BUFFER_SIZE = 2_000;
72
73 private static final int DISPLAY_LIMIT_HALF_DIVIDER = 2;
74
75
76
77
78
79
80
81
82 String getReadableBytes( final long bytes ) {
83 if( bytes > BYTES_PER_GIB_THRESHOLD ) {
84 return String.format( "%.3f GiB", bytes / CONVERSION_FACTOR_MIB / CONVERSION_FACTOR_KIB );
85 }else if( bytes > BYTES_PER_MIB_THRESHOLD ) {
86 return ( bytes / BYTES_PER_MIB_THRESHOLD ) + " MiB";
87 }else if( bytes > BYTES_PER_KIB_THRESHOLD ) {
88 return ( bytes / BYTES_PER_KIB_THRESHOLD ) + " KiB";
89 }else if( bytes > MINIMUM_BYTE_PLURAL_THRESHOLD ) {
90 return bytes + " bytes";
91 }else {
92 return bytes + " byte";
93 }
94 }
95
96
97
98
99
100
101
102
103 String getEndTimeFormatted( final long endTimeNano ) {
104 final double endTimeSec = endTimeNano / NANOSECONDS_PER_SECOND;
105 if( endTimeSec >= SECONDS_PER_TWO_HOURS ) {
106 return String.format( "%d Stunden %d Minuten %.3f Sekunden Laufzeit", ( (int) endTimeSec ) / SECONDS_PER_ONE_HOUR, ( (int) endTimeSec ) % SECONDS_PER_MINUTE,
107 endTimeSec % SECONDS_PER_MINUTE );
108 }else if( endTimeSec >= SECONDS_PER_ONE_HOUR ) {
109 return String.format( "%d Stunde %d Minuten %.3f Sekunden Laufzeit", ( (int) endTimeSec ) / SECONDS_PER_ONE_HOUR, ( (int) endTimeSec ) % SECONDS_PER_MINUTE,
110 endTimeSec % SECONDS_PER_MINUTE );
111 }else if( endTimeSec >= SECONDS_PER_MINUTE ) {
112 return String.format( "%d Minuten %.3f Sekunden Laufzeit", ( (int) endTimeSec ) / SECONDS_PER_MINUTE, endTimeSec % SECONDS_PER_MINUTE );
113 }else {
114 return String.format( "%.3f Sekunden Laufzeit", endTimeSec );
115 }
116 }
117
118
119
120
121
122
123
124
125
126
127
128 String formatMaps( final ScanType scanType, final Map<Path, FileAttributes> sourceMap, final Map<Path, FileAttributes> destMap, final Map<Path, FileAttributes> failMap ) {
129 final String line = System.lineSeparator();
130 final String scanFinish = "Scan abgeschlossen!\n";
131 final String tableSep = "------------------------------\n";
132 final StringBuilder stringBuilder = new StringBuilder( INITIAL_LOG_BUFFER_SIZE );
133
134 if( scanType == ScanType.SYNCHRONIZE ) {
135 stringBuilder.append( scanFinish ).append( "Zu kopieren in das Sourceverzeichnis:\n" ).append( tableSep );
136 if( sourceMap != null ) {
137 buildEntries( stringBuilder, sourceMap, DEFAULT_LOG_DISPLAY_LIMIT );
138 }
139 stringBuilder.append( line ).append( "Zu kopieren in das Zielverzeichnis:\n" ).append( tableSep );
140 if( destMap != null ) {
141 buildEntries( stringBuilder, destMap, DEFAULT_LOG_DISPLAY_LIMIT );
142 }
143 if( failMap != null && !failMap.isEmpty() ) {
144 stringBuilder.append( line ).append( "Zu löschende Dateien:\n" ).append( tableSep );
145 buildEntries( stringBuilder, failMap, DEFAULT_LOG_DISPLAY_LIMIT );
146 }
147 }else {
148 stringBuilder.append( scanFinish ).append( "Zu kopierende Dateien:\n" ).append( tableSep );
149 if( sourceMap != null ) {
150 buildEntries( stringBuilder, sourceMap, DEFAULT_LOG_DISPLAY_LIMIT );
151 }
152 stringBuilder.append( line ).append( "Zu löschende Dateien:\n" ).append( tableSep );
153 if( destMap != null ) {
154 buildEntries( stringBuilder, destMap, DEFAULT_LOG_DISPLAY_LIMIT );
155 }
156 if( failMap != null && !failMap.isEmpty() ) {
157 stringBuilder.append( line ).append( "Fehlerhafter Zugriff:\n" ).append( tableSep );
158 buildEntries( stringBuilder, failMap, DEFAULT_LOG_DISPLAY_LIMIT );
159 }
160 }
161 return stringBuilder.toString();
162 }
163
164
165
166
167
168
169
170
171
172
173 private StringBuilder buildEntries( final StringBuilder stringBuilder, final Map<Path, FileAttributes> printableMap, final int displayLimit ) {
174 final String valueSeparator = " , ";
175 int index = 0;
176 for( final Map.Entry<Path, FileAttributes> entry : printableMap.entrySet() ) {
177 final FileAttributes value = entry.getValue();
178 stringBuilder.append( value.getFileName() ).append( valueSeparator )
179 .append( getReadableBytes( value.getSize() ) ).append( valueSeparator )
180 .append( value.getModTimeString() ).append( valueSeparator )
181 .append( value.getCreateTimeString() ).append( valueSeparator )
182 .append( value.getFileHash() ).append( " " )
183 .append( entry.getKey().toString() )
184 .append( '\n' );
185
186 index++;
187 if( index > ( displayLimit / DISPLAY_LIMIT_HALF_DIVIDER ) ) {
188 break;
189 }
190 }
191 return stringBuilder;
192 }
193
194 }