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( final Path relativeFilePath, final String createTimeString, final FileTime createTime, final String modTimeString, final FileTime modTime, final long size,
62  			final String fileHash ) {
63  
64  		// Guard against null paths entering the tracking context
65  		this.relativeFilePath = Objects.requireNonNull( relativeFilePath, "Relative file path context cannot be null" );
66  		// Safely extract the file name string context even for root path definitions
67  		final Path namePath = relativeFilePath.getFileName();
68  		this.fileName = ( namePath != null ) ? namePath.toString() : relativeFilePath.toString();
69  
70  		this.createTime = ( createTime != null ) ? FileTime.fromMillis( createTime.toMillis() ) : FileTime.fromMillis( 0 );
71  		this.modTime = ( modTime != null ) ? FileTime.fromMillis( modTime.toMillis() ) : FileTime.fromMillis( 0 );
72  		this.createTimeString = createTimeString;
73  		this.modTimeString = modTimeString;
74  		this.size = size;
75  		this.fileHash = fileHash;
76  	}
77  
78  	/**
79  	 * Compares this file attribute record with another based primarily on file size metrics.
80  	 *
81  	 * @param o the other {@code FileAttributes} object to compare against
82  	 * @return a negative integer, zero, or a positive integer as this file size
83  	 *         is less than, equal to, or greater than the specified object's size
84  	 */
85  	@Override
86  	public int compareTo( final FileAttributes o ) {
87  		return Long.compare( this.size, o.getSize() );
88  	}
89  
90  	@Override
91  	public int hashCode() {
92  		final int prime = 31;
93  		int result = 1;
94  		result = prime * result + ( ( createTimeString == null ) ? 0 : createTimeString.hashCode() );
95  		result = prime * result + ( ( fileName == null ) ? 0 : fileName.hashCode() );
96  		result = prime * result + ( ( relativeFilePath == null ) ? 0 : relativeFilePath.hashCode() );
97  		result = prime * result + ( ( modTimeString == null ) ? 0 : modTimeString.hashCode() );
98  		result = prime * result + (int) ( size ^ ( size >>> 32 ) );
99  		return result;
100 	}
101 
102 	@Override
103 	public boolean equals( final Object obj ) {
104 		if( this == obj )
105 			return true;
106 		if( obj == null )
107 			return false;
108 		if( getClass() != obj.getClass() )
109 			return false;
110 		final FileAttributes other = (FileAttributes) obj;
111 		if( fileHash == null ) {
112 			if( other.fileHash != null )
113 				return false;
114 		}else if( !other.fileHash.equals( fileHash ) )
115 			return false;
116 		if( fileName == null ) {
117 			if( other.fileName != null )
118 				return false;
119 		}else if( !fileName.equals( other.fileName ) )
120 			return false;
121 		if( relativeFilePath == null ) {
122 			if( other.relativeFilePath != null )
123 				return false;
124 		}else if( !relativeFilePath.equals( other.relativeFilePath ) )
125 			return false;
126 		if( modTimeString == null ) {
127 			if( other.modTimeString != null )
128 				return false;
129 		}else if( !modTimeString.equals( other.modTimeString ) )
130 			return false;
131 		if( size != other.size )
132 			return false;
133 		return true;
134 	}
135 
136 	@Override
137 	public String toString() {
138 		return "FileAttributes [fileName=" + fileName + ", relativeFilePath=" + relativeFilePath + ", createTimeString="
139 				+ createTimeString + ", modTimeString=" + modTimeString + ", size=" + size + ", fileHash=" + fileHash
140 				+ ", createTime=" + createTime + ", modTime=" + modTime + "]";
141 	}
142 
143 	// --- Standard Java-Bean Property Accessors APIs layer ---
144 
145 	/**
146 	 * Retrieves the file path relative to the active deployment endpoint layer root.
147 	 *
148 	 * @return the relative {@link Path}
149 	 */
150 	public Path getRelativeFilePath() { return relativeFilePath; }
151 
152 	/**
153 	 * Retrieves the human-readable string mapping of the modification timeline entry.
154 	 *
155 	 * @return the modification timestamp string literal
156 	 */
157 	public String getModTimeString() { return modTimeString; }
158 
159 	/**
160 	 * Retrieves the native hardware accurate last modified metric vector.
161 	 *
162 	 * @return the high-precision modification {@link FileTime}
163 	 */
164 	public FileTime getModTime() { return FileTime.fromMillis( modTime.toMillis() ); }
165 
166 	/**
167 	 * Retrieves the human-readable string mapping of the original creation timeline entry.
168 	 *
169 	 * @return the creation timestamp string literal
170 	 */
171 	public String getCreateTimeString() { return createTimeString; }
172 
173 	/**
174 	 * Retrieves the data payload capacity volume layer quantified in bytes.
175 	 *
176 	 * @return the length of the file as a primitive long value
177 	 */
178 	public long getSize() { return size; }
179 
180 	/**
181 	 * Retrieves the unique data signature cryptographic validation token checksum.
182 	 *
183 	 * @return the string-formatted hexadecimal file hash
184 	 */
185 	public String getFileHash() { return fileHash; }
186 
187 	/**
188 	 * Retrieves the structural file name node excluding directory routing segments.
189 	 *
190 	 * @return the localized file name string representation
191 	 */
192 	public String getFileName() { return fileName; }
193 
194 	/**
195 	 * Retrieves the native hardware accurate original initialization filesystem creation marker.
196 	 *
197 	 * @return the high-precision creation {@link FileTime}
198 	 */
199 	public FileTime getCreateTime() { return FileTime.fromMillis( createTime.toMillis() ); }
200 }