1 package de.spiritscorp.datasync.io;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 import java.io.BufferedWriter;
24 import java.io.IOException;
25 import java.nio.file.Files;
26 import java.nio.file.Path;
27 import java.nio.file.StandardOpenOption;
28 import java.time.LocalDateTime;
29 import java.time.ZoneId;
30 import java.time.format.DateTimeFormatter;
31 import java.util.ArrayList;
32 import java.util.List;
33 import java.util.Objects;
34 import java.util.concurrent.locks.ReentrantLock;
35
36 import jakarta.json.Json;
37 import jakarta.json.JsonArray;
38 import jakarta.json.JsonException;
39 import jakarta.json.JsonObject;
40
41 import de.spiritscorp.datasync.model.FileAttributes;
42
43
44
45
46
47
48 public class Logger {
49
50
51 private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern( "dd.MM.yyyy HH:mm:ss" );
52
53
54 private final Path baseLogPath;
55
56
57 private final List<JsonArray> logCache = new ArrayList<>();
58
59
60 private final ReentrantLock threadLock = new ReentrantLock();
61
62
63
64
65
66 public Logger() {
67 this(
68 PreferenceManager.getInstance().getLogPath(),
69 new Logrotater(
70 10_485_760L,
71 5 ) );
72 }
73
74
75
76
77
78
79
80
81
82 Logger( final Path baseLogPath, final Logrotater rotater ) {
83 this.baseLogPath = Objects.requireNonNull( baseLogPath, "baseLogPath must not be null" );
84
85 rotater.executeLogRotationIfNeeded( baseLogPath );
86 }
87
88
89
90
91
92
93
94
95 public void setEntry( final String filePath, final String changeStatus, final FileAttributes fileAttributes ) {
96 threadLock.lock();
97 try {
98 final JsonObject jsonObject = Json.createObjectBuilder()
99 .add( "Dateiname", fileAttributes.getFileName() )
100 .add( "erstellt", fileAttributes.getCreateTimeString() )
101 .add( "zuletzt modifiziert", fileAttributes.getModTimeString() )
102 .add( "Größe", fileAttributes.getSize() )
103 .add( "Fingerabdruck", ( fileAttributes.getFileHash() == null ) ? "null" : fileAttributes.getFileHash() )
104 .build();
105
106 final JsonArray jsonArray = Json.createArrayBuilder()
107 .add( filePath )
108 .add( LocalDateTime.now( ZoneId.systemDefault() ).format( DATE_FORMATTER ) )
109 .add( changeStatus )
110 .add( jsonObject )
111 .build();
112
113 logCache.add( jsonArray );
114 }finally {
115 threadLock.unlock();
116 }
117 }
118
119
120
121
122
123 public void printStatus() {
124 threadLock.lock();
125 try {
126 if( logCache.isEmpty() ) { return; }
127
128 try( BufferedWriter writer = Files.newBufferedWriter(
129 baseLogPath,
130 StandardOpenOption.CREATE,
131 StandardOpenOption.APPEND ) ) {
132
133 for( final JsonArray logEntry : logCache ) {
134 writer.write( logEntry.toString() );
135 writer.newLine();
136 }
137
138 logCache.clear();
139 }catch( final IOException exception ) {
140 Debug.printDebug( "[Logger] can´t write log file at -> %s", baseLogPath );
141 Debug.printException( this.getClass(), exception );
142 }
143 }finally {
144 threadLock.unlock();
145 }
146 }
147
148
149
150
151
152
153
154 public List<JsonArray> readLogForGui() {
155 final List<JsonArray> invertedGuiList = new ArrayList<>();
156
157 if( !Files.exists( baseLogPath ) ) { return invertedGuiList; }
158
159 threadLock.lock();
160 String currentLine = "";
161 try {
162 final List<String> lines = Files.readAllLines( baseLogPath );
163 for( int i = lines.size() - 1; i >= 0; i-- ) {
164 currentLine = lines.get( i ).trim();
165 if( currentLine.isEmpty() ) continue;
166 invertedGuiList.add( Json.createArrayBuilder().add( currentLine ).build() );
167 }
168 }catch( final JsonException exception ) {
169 Debug.printDebug( "[Logger] Invalid JSON in log line: %s", currentLine );
170 Debug.printException( this.getClass(), exception );
171 }catch( final IOException exception ) {
172 Debug.printDebug( "[Logger] can´t read log file at -> %s", baseLogPath );
173 Debug.printException( this.getClass(), exception );
174 }finally {
175 threadLock.unlock();
176 }
177 return invertedGuiList;
178 }
179 }