View Javadoc
1   package de.spiritscorp.datasync.model;
2   
3   /*-
4    * 		Data Sync
5    *
6    * 		Copyright ©   2022    The Spirit
7    * 		@email                        thespirit@spiritscorp.network
8    *
9    * 		This program is free software; you can redistribute it and/or modify
10   * 		it under the terms of the GNU General Public License as published by
11   * 		the Free Software Foundation; either version 3 of the License, or
12   * 		(at your option) any later version.
13   *
14   * 		This program is distributed in the hope that it will be useful,
15   * 		but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * 		MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17   * 		See the GNU General Public License for more details.
18   *
19   * 		You should have received a copy of the GNU General Public License
20   * 		along with this program. If not, see <http://www.gnu.org/licenses/>.
21   */
22  
23  import java.io.BufferedInputStream;
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.nio.file.attribute.BasicFileAttributes;
29  import java.nio.file.attribute.FileTime;
30  import java.security.MessageDigest;
31  import java.security.NoSuchAlgorithmException;
32  import java.time.ZoneId;
33  import java.time.format.DateTimeFormatter;
34  import java.util.Map;
35  
36  import de.spiritscorp.datasync.ScanType;
37  import de.spiritscorp.datasync.io.Debug;
38  
39  class FileScan implements Runnable {
40  
41  	private final Path path;
42  	private final Path startPath;
43  	private final Map<Path, FileAttributes> map;
44  	private final ScanType scanType;
45  	private final BasicFileAttributes bfa;
46  
47  	/**
48  	 * Scan the attributes of one file
49  	 *
50  	 * @param path
51  	 * @param startPath
52  	 * @param map
53  	 * @param scanType
54  	 */
55  	FileScan( Path path, Path startPath, Map<Path, FileAttributes> map, ScanType scanType, BasicFileAttributes bfa ) {
56  		this.path = path;
57  		this.startPath = startPath;
58  		this.map = map;
59  		this.scanType = scanType;
60  		this.bfa = bfa;
61  	}
62  
63  	@Override
64  	public void run() {
65  		final FileAttributes fileAttributes = new FileAttributes(
66  				relativePath(),
67  				fileTimeToString( bfa.creationTime() ),
68  				bfa.creationTime(),
69  				fileTimeToString( bfa.lastModifiedTime() ),
70  				bfa.lastModifiedTime(),
71  				bfa.size(),
72  				deepScan() );
73  		map.put( path, fileAttributes );
74  	}
75  
76  	private String getSha256() {
77  		final StringBuilder builder = new StringBuilder();
78  		try( BufferedInputStream bis = new BufferedInputStream( Files.newInputStream( path, StandardOpenOption.READ ) ) ) {
79  			final MessageDigest messageDigest = MessageDigest.getInstance( "SHA-256" );
80  			byte[] input;
81  			while( bis.available() != 0 ) {
82  				input = bis.readNBytes( 8192 );
83  				messageDigest.update( input );
84  			}
85  			final byte[] digestByte = messageDigest.digest();
86  			for( final byte b : digestByte ) {
87  				builder.append( Integer.toString( ( b & 0xff ) + 0x100, 16 ).substring( 1 ) );
88  			}
89  		}catch( IOException | NoSuchAlgorithmException e ) {
90  			builder.delete( 0, builder.length() );
91  			builder.append( "Failed" );
92  			Debug.printDebug( "[FileScan] Failed: %s Message: %s", path, e.getMessage() );
93  			Debug.printException( this.getClass(), e );
94  		}
95  		return builder.toString();
96  	}
97  
98  	private String fileTimeToString( final FileTime fileTime ) {
99  		return fileTime.toInstant().atZone( ZoneId.systemDefault() ).toLocalDateTime().format( DateTimeFormatter.ofPattern( "dd.MM.yyyy  HH:mm:ss" ) );
100 	}
101 
102 	private Path relativePath() {
103 		return startPath.relativize( path );
104 	}
105 
106 	private String deepScan() {
107 		return switch( scanType ) {
108 			case DEEP_SCAN, DUBLICATE_SCAN -> getSha256();
109 			case FLAT_SCAN, SYNCHRONIZE -> "null";
110 			default -> "null";
111 		};
112 	}
113 }