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.nio.file.Path;
24  import java.nio.file.attribute.FileTime;
25  import java.util.Objects;
26  
27  /**
28   * Immutable value object representing the metadata and diagnostic attributes of a file
29   * managed within the synchronization engine context.
30   * <p>
31   * This class stores timestamps, cryptographic checksums, sizes, and path configurations
32   * required to compute delta states between replication nodes.
33   * <p>
34   *
35   * @author Tom Spirit
36   * @version 2.0.0
37   */
38  public final class FileAttributes implements Comparable<FileAttributes> {
39  
40  	private final Path relativeFilePath;
41  	private final String fileName;
42  	private final String createTimeString;
43  	private final String modTimeString;
44  	private final long size;
45  	private final String fileHash;
46  	private final FileTime createTime;
47  	private final FileTime modTime;
48  
49  	/**
50  	 * Constructs a comprehensive metadata record for a single tracked file.
51  	 *
52  	 * @param relativeFilePath the target file path relative to the source or destination root directory
53  	 * @param createTimeString a string representation of the file creation timestamp
54  	 * @param createTime       the raw {@link FileTime} of when the file was created
55  	 * @param modTimeString    a string representation of the last modification timestamp
56  	 * @param modTime          the raw {@link FileTime} of the last modification event
57  	 * @param size             the size of the file in bytes
58  	 * @param fileHash         the cryptographic checksum signature (SHA-256 or higher)
59  	 * @throws NullPointerException if {@code relativeFilePath} is null
60  	 */
61  	public FileAttributes( Path relativeFilePath, String createTimeString, FileTime createTime, String modTimeString, FileTime modTime, long size, String fileHash ) {
62  
63  		// Guard against null paths entering the tracking context
64  		this.relativeFilePath = Objects.requireNonNull( relativeFilePath, "Relative file path context cannot be null" );
65  		// Safely extract the file name string context even for root path definitions
66  		final Path namePath = relativeFilePath.getFileName();
67  		this.fileName = ( namePath != null ) ? namePath.toString() : relativeFilePath.toString();
68  
69  		this.createTime = ( createTime != null ) ? FileTime.fromMillis( createTime.toMillis() ) : FileTime.fromMillis( 0 );
70  		this.modTime = ( modTime != null ) ? FileTime.fromMillis( modTime.toMillis() ) : FileTime.fromMillis( 0 );
71  		this.createTimeString = createTimeString;
72  		this.modTimeString = modTimeString;
73  		this.size = size;
74  		this.fileHash = fileHash;
75  	}
76  
77  	/**
78  	 * Compares this file attribute record with another based primarily on file size metrics.
79  	 *
80  	 * @param o the other {@code FileAttributes} object to compare against
81  	 * @return a negative integer, zero, or a positive integer as this file size
82  	 *         is less than, equal to, or greater than the specified object's size
83  	 */
84  	@Override
85  	public int compareTo( FileAttributes o ) {
86  		return Long.compare( this.size, o.getSize() );
87  	}
88  
89  	@Override
90  	public int hashCode() {
91  		final int prime = 31;
92  		int result = 1;
93  		result = prime * result + ( ( createTimeString == null ) ? 0 : createTimeString.hashCode() );
94  		result = prime * result + ( ( fileName == null ) ? 0 : fileName.hashCode() );
95  		result = prime * result + ( ( relativeFilePath == null ) ? 0 : relativeFilePath.hashCode() );
96  		result = prime * result + ( ( modTimeString == null ) ? 0 : modTimeString.hashCode() );
97  		result = prime * result + (int) ( size ^ ( size >>> 32 ) );
98  		return result;
99  	}
100 
101 	@Override
102 	public boolean equals( Object obj ) {
103 		if( this == obj )
104 			return true;
105 		if( obj == null )
106 			return false;
107 		if( getClass() != obj.getClass() )
108 			return false;
109 		final FileAttributes other = (FileAttributes) obj;
110 		if( fileHash == null ) {
111 			if( other.fileHash != null )
112 				return false;
113 		}else if( !other.fileHash.equals( fileHash ) )
114 			return false;
115 		if( fileName == null ) {
116 			if( other.fileName != null )
117 				return false;
118 		}else if( !fileName.equals( other.fileName ) )
119 			return false;
120 		if( relativeFilePath == null ) {
121 			if( other.relativeFilePath != null )
122 				return false;
123 		}else if( !relativeFilePath.equals( other.relativeFilePath ) )
124 			return false;
125 		if( modTimeString == null ) {
126 			if( other.modTimeString != null )
127 				return false;
128 		}else if( !modTimeString.equals( other.modTimeString ) )
129 			return false;
130 		if( size != other.size )
131 			return false;
132 		return true;
133 	}
134 
135 	@Override
136 	public String toString() {
137 		return "FileAttributes [fileName=" + fileName + ", relativeFilePath=" + relativeFilePath + ", createTimeString="
138 				+ createTimeString + ", modTimeString=" + modTimeString + ", size=" + size + ", fileHash=" + fileHash
139 				+ ", createTime=" + createTime + ", modTime=" + modTime + "]";
140 	}
141 
142 	// --- Standard Java-Bean Property Accessors APIs layer ---
143 
144 	/**
145 	 * Retrieves the file path relative to the active deployment endpoint layer root.
146 	 *
147 	 * @return the relative {@link Path}
148 	 */
149 	public Path getRelativeFilePath() { return relativeFilePath; }
150 
151 	/**
152 	 * Retrieves the human-readable string mapping of the modification timeline entry.
153 	 *
154 	 * @return the modification timestamp string literal
155 	 */
156 	public String getModTimeString() { return modTimeString; }
157 
158 	/**
159 	 * Retrieves the native hardware accurate last modified metric vector.
160 	 *
161 	 * @return the high-precision modification {@link FileTime}
162 	 */
163 	public FileTime getModTime() { return FileTime.fromMillis( modTime.toMillis() ); }
164 
165 	/**
166 	 * Retrieves the human-readable string mapping of the original creation timeline entry.
167 	 *
168 	 * @return the creation timestamp string literal
169 	 */
170 	public String getCreateTimeString() { return createTimeString; }
171 
172 	/**
173 	 * Retrieves the data payload capacity volume layer quantified in bytes.
174 	 *
175 	 * @return the length of the file as a primitive long value
176 	 */
177 	public long getSize() { return size; }
178 
179 	/**
180 	 * Retrieves the unique data signature cryptographic validation token checksum.
181 	 *
182 	 * @return the string-formatted hexadecimal file hash
183 	 */
184 	public String getFileHash() { return fileHash; }
185 
186 	/**
187 	 * Retrieves the structural file name node excluding directory routing segments.
188 	 *
189 	 * @return the localized file name string representation
190 	 */
191 	public String getFileName() { return fileName; }
192 
193 	/**
194 	 * Retrieves the native hardware accurate original initialization filesystem creation marker.
195 	 *
196 	 * @return the high-precision creation {@link FileTime}
197 	 */
198 	public FileTime getCreateTime() { return FileTime.fromMillis( createTime.toMillis() ); }
199 }