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.IOException;
24 import java.io.OutputStream;
25 import java.nio.file.Files;
26 import java.nio.file.Path;
27 import java.nio.file.Paths;
28 import java.nio.file.StandardOpenOption;
29 import java.nio.file.attribute.FileTime;
30 import java.util.HashMap;
31 import java.util.Map;
32
33 import de.spiritscorp.datasync.model.FileAttributes;
34 import jakarta.json.Json;
35 import jakarta.json.JsonObject;
36 import jakarta.json.JsonObjectBuilder;
37 import jakarta.json.JsonReader;
38 import jakarta.json.JsonValue;
39 import jakarta.json.JsonWriter;
40 import jakarta.json.JsonWriterFactory;
41 import jakarta.json.stream.JsonGenerator;
42
43
44
45
46
47 class IOSyncMap {
48
49 private final Path jobSyncMapPath;
50
51
52
53
54 IOSyncMap( String jobName ) {
55 this.jobSyncMapPath = PreferenceManager.getInstance().getConfigPath().getParent().resolve( "syncMap_" + jobName + ".json" );
56 }
57
58 boolean loadSyncMap( Map<Path, FileAttributes> syncMap ) {
59 if( !syncMap.isEmpty() || !Files.exists( jobSyncMapPath ) ) { return false; }
60 try( JsonReader jsonReader = Json.createReader( Files.newInputStream( jobSyncMapPath, StandardOpenOption.READ ) ) ) {
61 final JsonObject jsonObject = jsonReader.readObject();
62
63 for( final Map.Entry<String, JsonValue> entry : jsonObject.entrySet() ) {
64 final JsonObject objectEntry = entry.getValue().asJsonObject();
65 final FileAttributes fileAttributes = new FileAttributes(
66 Paths.get( objectEntry.getString( "relativeFilePath" ) ),
67 objectEntry.getString( "createTimeString" ),
68 FileTime.fromMillis( Long.parseLong( objectEntry.get( "createTime" ).toString() ) ),
69 objectEntry.getString( "modTimeString" ),
70 FileTime.fromMillis( Long.parseLong( objectEntry.get( "modTime" ).toString() ) ),
71 Long.parseLong( objectEntry.get( "size" ).toString() ),
72 objectEntry.getString( "fileHash" ) );
73 syncMap.put( Paths.get( objectEntry.getString( "relativeFilePath" ) ), fileAttributes );
74 }
75 return true;
76 }catch( final IllegalArgumentException | UnsupportedOperationException | SecurityException | IOException e ) {
77
78 Debug.printDebug( "[Error] File system or configuration failure while opening stream: %s", e.getMessage() );
79 Debug.printException( this.getClass(), e );
80 return false;
81
82 }catch( final jakarta.json.JsonException e ) {
83
84 Debug.printDebug( "[Error] JSON processing or syntax error: %s", e.getMessage() );
85 Debug.printException( this.getClass(), e );
86 return false;
87
88 }catch( final IllegalStateException e ) {
89
90 Debug.printDebug( "[Error] Parser state conflict: %s", e.getMessage() );
91 Debug.printException( this.getClass(), e );
92 return false;
93 }
94 }
95
96 void writeSyncMap( Map<Path, FileAttributes> syncMap ) {
97 try( OutputStream os = Files.newOutputStream( jobSyncMapPath, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING ) ) {
98 final HashMap<String, Boolean> config = new HashMap<>();
99 config.put( JsonGenerator.PRETTY_PRINTING, true );
100 final JsonWriterFactory jwf = Json.createWriterFactory( config );
101
102 final JsonObject jobObj = createSyncMap( syncMap );
103 final JsonWriter jw = jwf.createWriter( os );
104 jw.write( jobObj );
105 jw.close();
106 }catch( final IOException e ) {
107 Debug.printException( this.getClass(), e );
108 }
109 }
110
111 private JsonObject createSyncMap( Map<Path, FileAttributes> syncMap ) {
112 final JsonObjectBuilder jo = Json.createObjectBuilder();
113 for( final Map.Entry<Path, FileAttributes> entry : syncMap.entrySet() ) {
114 final JsonObject jo2 = Json.createObjectBuilder()
115 .add( "relativeFilePath", entry.getValue().getRelativeFilePath().toString() )
116 .add( "fileHash", entry.getValue().getFileHash() )
117 .add( "modTimeString", entry.getValue().getModTimeString() )
118 .add( "createTime", entry.getValue().getCreateTime().toMillis() )
119 .add( "modTime", entry.getValue().getModTime().toMillis() )
120 .add( "size", entry.getValue().getSize() )
121 .add( "createTimeString", entry.getValue().getCreateTimeString() )
122 .build();
123 jo.add( entry.getValue().getRelativeFilePath().toString(), jo2 );
124 }
125 return jo.build();
126 }
127 }