View Javadoc
1   /*
2    * dpkg - Debian Package library and the Debian Package Maven plugin
3    * (c) Copyright 2016 Gerrit Hohl
4    *
5    * This program is free software; you can redistribute it and/or
6    * modify it under the terms of the GNU General Public License
7    * as published by the Free Software Foundation; either version 2
8    * of the License, or (at your option) any later version.
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with this program; if not, write to the Free Software
17   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18   */
19  package net.sourceforge.javadpkg.io.impl;
20  
21  import java.util.Date;
22  
23  import net.sourceforge.javadpkg.io.FileMetaData;
24  import net.sourceforge.javadpkg.io.FileMode;
25  import net.sourceforge.javadpkg.io.FileOwner;
26  
27  /**
28   * <p>
29   * A {@link FileMetaData} implementation.
30   * </p>
31   *
32   * @author Gerrit Hohl (gerrit-hohl@users.sourceforge.net)
33   * @version <b>1.0</b>, 12.05.2016 by Gerrit Hohl
34   */
35  public class FileMetaDataImpl implements FileMetaData {
36  	
37  	
38  	/** The path of the file excluding the name. */
39  	private String		path;
40  	/** The name of the file. */
41  	private String		name;
42  	/** The flag if the file is a directory. */
43  	private boolean		directory;
44  	/** The target path of the symbolic link. */
45  	private String		targetPath;
46  	/** The owner of the file. */
47  	private FileOwner	owner;
48  	/** The mode of the file. */
49  	private FileMode	mode;
50  	/** The length of the file. */
51  	private long		length;
52  	/** The timestamp of the last modification. */
53  	private Date		lastModifiedDate;
54  	
55  	
56  	/**
57  	 * <p>
58  	 * Creates the meta data of a directory.
59  	 * </p>
60  	 *
61  	 * @param path
62  	 *            The path of the file excluding the name.
63  	 * @param name
64  	 *            The name of the file.
65  	 * @param owner
66  	 *            The owner of the file.
67  	 * @param mode
68  	 *            The mode of the file.
69  	 * @param lastModifiedDate
70  	 *            The timestamp of the last modification.
71  	 * @throws IllegalArgumentException
72  	 *             If any of the parameters are <code>null</code>, the path is
73  	 *             empty, the name contains a slash or is empty also the path is
74  	 *             not &quot;/&quot;.
75  	 */
76  	public FileMetaDataImpl(String path, String name, FileOwner owner, FileMode mode, Date lastModifiedDate) {
77  		super();
78  
79  		if (path == null)
80  			throw new IllegalArgumentException("Argument path is null.");
81  		if (path.isEmpty())
82  			throw new IllegalArgumentException("Argument path is empty.");
83  		if (name == null)
84  			throw new IllegalArgumentException("Argument name is null.");
85  		if (name.indexOf('/') != -1)
86  			throw new IllegalArgumentException("Argument name contains a slash: " + name);
87  		if (owner == null)
88  			throw new IllegalArgumentException("Argument owner is null.");
89  		if (mode == null)
90  			throw new IllegalArgumentException("Argument mode is null.");
91  		if (lastModifiedDate == null)
92  			throw new IllegalArgumentException("Argument lastModifiedDate is null.");
93  		
94  		this.path = this.revisePath(path);
95  		if (name.isEmpty() && !"/".equals(path))
96  			throw new IllegalArgumentException("An empty name is only valid for the root. Path: " + path);
97  		this.name = name;
98  		this.directory = true;
99  		this.targetPath = null;
100 		this.owner = owner;
101 		this.mode = mode;
102 		this.length = -1;
103 		this.lastModifiedDate = lastModifiedDate;
104 	}
105 	
106 	
107 	/**
108 	 * <p>
109 	 * Creates the meta data of a directory.
110 	 * </p>
111 	 *
112 	 * @param parent
113 	 *            The parent directory.
114 	 * @param name
115 	 *            The name of the file.
116 	 * @param owner
117 	 *            The owner of the file.
118 	 * @param mode
119 	 *            The mode of the file.
120 	 * @param lastModifiedDate
121 	 *            The timestamp of the last modification.
122 	 * @throws IllegalArgumentException
123 	 *             If any of the parameters are <code>null</code>, the parent is
124 	 *             not a directory, the name contains a slash or is empty.
125 	 */
126 	public FileMetaDataImpl(FileMetaData parent, String name, FileOwner owner, FileMode mode, Date lastModifiedDate) {
127 		super();
128 
129 		if (parent == null)
130 			throw new IllegalArgumentException("Argument path is null.");
131 		if (!parent.isDirectory())
132 			throw new IllegalArgumentException("Argument parent |" + parent.getAbsolutePath() + "| is not a directory.");
133 		if (name == null)
134 			throw new IllegalArgumentException("Argument name is null.");
135 		if (name.isEmpty())
136 			throw new IllegalArgumentException("An empty name is only valid for the root. Path: " + parent.getAbsolutePath());
137 		if (name.indexOf('/') != -1)
138 			throw new IllegalArgumentException("Argument name contains a slash: " + name);
139 		if (owner == null)
140 			throw new IllegalArgumentException("Argument owner is null.");
141 		if (mode == null)
142 			throw new IllegalArgumentException("Argument mode is null.");
143 		if (lastModifiedDate == null)
144 			throw new IllegalArgumentException("Argument lastModifiedDate is null.");
145 		
146 		this.path = parent.getAbsolutePath();
147 		this.name = name;
148 		this.directory = true;
149 		this.targetPath = null;
150 		this.owner = owner;
151 		this.mode = mode;
152 		this.length = -1;
153 		this.lastModifiedDate = lastModifiedDate;
154 	}
155 	
156 	
157 	/**
158 	 * <p>
159 	 * Creates the meta data of a regular file.
160 	 * </p>
161 	 *
162 	 * @param path
163 	 *            The path of the file excluding the name.
164 	 * @param name
165 	 *            The name of the file.
166 	 * @param owner
167 	 *            The owner of the file.
168 	 * @param mode
169 	 *            The mode of the file.
170 	 * @param length
171 	 *            The length of the file or <code>-1</code>, if the length is
172 	 *            unknown.
173 	 * @param lastModifiedDate
174 	 *            The timestamp of the last modification.
175 	 * @throws IllegalArgumentException
176 	 *             If any of the parameters are <code>null</code>, the path is
177 	 *             empty, the name contains a slash, the name is empty or the
178 	 *             length is less than <code>-1</code>.
179 	 */
180 	public FileMetaDataImpl(String path, String name, FileOwner owner, FileMode mode, long length, Date lastModifiedDate) {
181 		super();
182 
183 		if (path == null)
184 			throw new IllegalArgumentException("Argument path is null.");
185 		if (path.isEmpty())
186 			throw new IllegalArgumentException("Argument path is empty.");
187 		if (name == null)
188 			throw new IllegalArgumentException("Argument name is null.");
189 		if (name.isEmpty())
190 			throw new IllegalArgumentException("Argument name is empty.");
191 		if (name.indexOf('/') != -1)
192 			throw new IllegalArgumentException("Argument name contains a slash: " + name);
193 		if (owner == null)
194 			throw new IllegalArgumentException("Argument owner is null.");
195 		if (mode == null)
196 			throw new IllegalArgumentException("Argument mode is null.");
197 		if (length < -1)
198 			throw new IllegalArgumentException("Argument length is less than -1: " + length);
199 		if (lastModifiedDate == null)
200 			throw new IllegalArgumentException("Argument lastModifiedDate is null.");
201 		
202 		this.path = this.revisePath(path);
203 		this.name = name;
204 		this.directory = false;
205 		this.targetPath = null;
206 		this.owner = owner;
207 		this.mode = mode;
208 		this.length = length;
209 		this.lastModifiedDate = lastModifiedDate;
210 	}
211 
212 
213 	/**
214 	 * <p>
215 	 * Creates the meta data of a regular file.
216 	 * </p>
217 	 *
218 	 * @param parent
219 	 *            The parent directory.
220 	 * @param name
221 	 *            The name of the file.
222 	 * @param owner
223 	 *            The owner of the file.
224 	 * @param mode
225 	 *            The mode of the file.
226 	 * @param length
227 	 *            The length of the file or <code>-1</code>, if the length is
228 	 *            unknown.
229 	 * @param lastModifiedDate
230 	 *            The timestamp of the last modification.
231 	 * @throws IllegalArgumentException
232 	 *             If any of the parameters are <code>null</code>, the parent is
233 	 *             not a directory, the name contains a slash or the length is
234 	 *             less than <code>-1</code>.
235 	 */
236 	public FileMetaDataImpl(FileMetaData parent, String name, FileOwner owner, FileMode mode, long length,
237 			Date lastModifiedDate) {
238 		
239 		super();
240 
241 		if (parent == null)
242 			throw new IllegalArgumentException("Argument path is null.");
243 		if (!parent.isDirectory())
244 			throw new IllegalArgumentException("Argument parent |" + parent.getAbsolutePath() + "| is not a directory.");
245 		if (name == null)
246 			throw new IllegalArgumentException("Argument name is null.");
247 		if (name.isEmpty())
248 			throw new IllegalArgumentException("Argument name is empty.");
249 		if (name.indexOf('/') != -1)
250 			throw new IllegalArgumentException("Argument name contains a slash: " + name);
251 		if (owner == null)
252 			throw new IllegalArgumentException("Argument owner is null.");
253 		if (mode == null)
254 			throw new IllegalArgumentException("Argument mode is null.");
255 		if (length < -1)
256 			throw new IllegalArgumentException("Argument length is less than -1: " + length);
257 		if (lastModifiedDate == null)
258 			throw new IllegalArgumentException("Argument lastModifiedDate is null.");
259 		
260 		this.path = parent.getAbsolutePath();
261 		this.name = name;
262 		this.directory = false;
263 		this.targetPath = null;
264 		this.owner = owner;
265 		this.mode = mode;
266 		this.length = length;
267 		this.lastModifiedDate = lastModifiedDate;
268 	}
269 
270 
271 	/**
272 	 * <p>
273 	 * Creates the meta data of a symbolic link.
274 	 * </p>
275 	 *
276 	 * @param path
277 	 *            The path of the file excluding the name.
278 	 * @param name
279 	 *            The name of the file.
280 	 * @param targetPath
281 	 *            The target path of the symbolic link.
282 	 * @param owner
283 	 *            The owner of the file.
284 	 * @param mode
285 	 *            The mode of the file.
286 	 * @param lastModifiedDate
287 	 *            The timestamp of the last modification.
288 	 * @throws IllegalArgumentException
289 	 *             If any of the parameters are <code>null</code>, the path is
290 	 *             empty, the name contains a slash, the path is empty or if the
291 	 *             target path is empty.
292 	 */
293 	public FileMetaDataImpl(String path, String name, String targetPath, FileOwner owner, FileMode mode,
294 			Date lastModifiedDate) {
295 		
296 		super();
297 
298 		if (path == null)
299 			throw new IllegalArgumentException("Argument path is null.");
300 		if (path.isEmpty())
301 			throw new IllegalArgumentException("Argument path is empty.");
302 		if (name == null)
303 			throw new IllegalArgumentException("Argument name is null.");
304 		if (name.indexOf('/') != -1)
305 			throw new IllegalArgumentException("Argument name contains a slash: " + name);
306 		if (targetPath == null)
307 			throw new IllegalArgumentException("Argument targetPath is null.");
308 		if (targetPath.isEmpty())
309 			throw new IllegalArgumentException("Argument targetPath is empty.");
310 		if (owner == null)
311 			throw new IllegalArgumentException("Argument owner is null.");
312 		if (mode == null)
313 			throw new IllegalArgumentException("Argument mode is null.");
314 		if (lastModifiedDate == null)
315 			throw new IllegalArgumentException("Argument lastModifiedDate is null.");
316 		
317 		this.path = this.revisePath(path);
318 		this.name = name;
319 		this.directory = false;
320 		this.targetPath = targetPath;
321 		this.owner = owner;
322 		this.mode = mode;
323 		this.length = -1;
324 		this.lastModifiedDate = lastModifiedDate;
325 	}
326 	
327 	
328 	/**
329 	 * <p>
330 	 * Creates the meta data of a symbolic link.
331 	 * </p>
332 	 *
333 	 * @param parent
334 	 *            The parent directory.
335 	 * @param name
336 	 *            The name of the file.
337 	 * @param targetPath
338 	 *            The target path of the symbolic link.
339 	 * @param owner
340 	 *            The owner of the file.
341 	 * @param mode
342 	 *            The mode of the file.
343 	 * @param lastModifiedDate
344 	 *            The timestamp of the last modification.
345 	 * @throws IllegalArgumentException
346 	 *             If any of the parameters are <code>null</code>, the parent is
347 	 *             not a directory, the name contains a slash, the name is empty
348 	 *             or the target path is empty.
349 	 */
350 	public FileMetaDataImpl(FileMetaData parent, String name, String targetPath, FileOwner owner, FileMode mode,
351 			Date lastModifiedDate) {
352 		super();
353 
354 		if (parent == null)
355 			throw new IllegalArgumentException("Argument path is null.");
356 		if (!parent.isDirectory())
357 			throw new IllegalArgumentException("Argument parent |" + parent.getAbsolutePath() + "| is not a directory.");
358 		if (name == null)
359 			throw new IllegalArgumentException("Argument name is null.");
360 		if (name.isEmpty())
361 			throw new IllegalArgumentException("An empty name is only valid for the root. Path: " + parent.getAbsolutePath());
362 		if (name.indexOf('/') != -1)
363 			throw new IllegalArgumentException("Argument name contains a slash: " + name);
364 		if (targetPath == null)
365 			throw new IllegalArgumentException("Argument targetPath is null.");
366 		if (targetPath.isEmpty())
367 			throw new IllegalArgumentException("Argument targetPath is empty.");
368 		if (owner == null)
369 			throw new IllegalArgumentException("Argument owner is null.");
370 		if (mode == null)
371 			throw new IllegalArgumentException("Argument mode is null.");
372 		if (lastModifiedDate == null)
373 			throw new IllegalArgumentException("Argument lastModifiedDate is null.");
374 		
375 		this.path = parent.getAbsolutePath();
376 		this.name = name;
377 		this.directory = false;
378 		this.targetPath = targetPath;
379 		this.owner = owner;
380 		this.mode = mode;
381 		this.length = -1;
382 		this.lastModifiedDate = lastModifiedDate;
383 	}
384 
385 
386 	/**
387 	 * <p>
388 	 * Revises the path by making sure that it starts with a slash and ends with
389 	 * a slash.
390 	 * </p>
391 	 *
392 	 * @param path
393 	 *            The path.
394 	 * @return The revised path.
395 	 */
396 	private String revisePath(String path) {
397 		String result;
398 		
399 		
400 		result = path;
401 		if (result.startsWith("./")) {
402 			result = result.substring(1);
403 		}
404 		if (!result.startsWith("/")) {
405 			result = '/' + result;
406 		}
407 		if (!result.endsWith("/")) {
408 			result = result + '/';
409 		}
410 		
411 		return result;
412 	}
413 
414 
415 	@Override
416 	public String getPath() {
417 		return this.path;
418 	}
419 	
420 	
421 	@Override
422 	public String getName() {
423 		return this.name;
424 	}
425 
426 
427 	@Override
428 	public String getAbsolutePath() {
429 		StringBuilder sb;
430 		
431 		
432 		sb = new StringBuilder();
433 		sb.append(this.path);
434 		sb.append(this.name);
435 		if (this.directory && !this.name.isEmpty()) {
436 			sb.append('/');
437 		}
438 		return sb.toString();
439 	}
440 
441 
442 	@Override
443 	public boolean isFile() {
444 		return !this.directory;
445 	}
446 
447 
448 	@Override
449 	public boolean isDirectory() {
450 		return this.directory;
451 	}
452 
453 
454 	@Override
455 	public boolean isSymbolicLink() {
456 		return (this.targetPath != null);
457 	}
458 
459 
460 	@Override
461 	public String getTargetPath() {
462 		return this.targetPath;
463 	}
464 	
465 	
466 	@Override
467 	public FileOwner getOwner() {
468 		return this.owner;
469 	}
470 
471 
472 	@Override
473 	public FileMode getMode() {
474 		return this.mode;
475 	}
476 
477 
478 	@Override
479 	public String getModeAsText() {
480 		StringBuilder sb;
481 
482 
483 		sb = new StringBuilder();
484 		if (this.directory) {
485 			sb.append('d');
486 		} else if (this.targetPath != null) {
487 			sb.append('l');
488 		} else {
489 			sb.append('-');
490 		}
491 		sb.append(this.mode.getText());
492 
493 		return sb.toString();
494 	}
495 	
496 	
497 	@Override
498 	public long getLength() {
499 		return this.length;
500 	}
501 
502 
503 	@Override
504 	public Date getLastModifiedDate() {
505 		return this.lastModifiedDate;
506 	}
507 
508 
509 	/**
510 	 * <p>
511 	 * Creates the meta data for a directory.
512 	 * </p>
513 	 *
514 	 * @param absolutePath
515 	 *            The absolute path.
516 	 * @param owner
517 	 *            The owner of the file.
518 	 * @param mode
519 	 *            The mode of the file.
520 	 * @param lastModifiedDate
521 	 *            The timestamp of the last modification.
522 	 * @return The meta data.
523 	 * @throws IllegalArgumentException
524 	 *             If any of the parameters are <code>null</code> or the
525 	 *             absolute path is empty.
526 	 */
527 	public static FileMetaData createDirectoryMetaData(String absolutePath, FileOwner owner, FileMode mode,
528 			Date lastModifiedDate) {
529 		
530 		FileMetaData directory;
531 		String[] paths;
532 		
533 		
534 		if (absolutePath == null)
535 			throw new IllegalArgumentException("Argument absolutePath is null.");
536 		if (absolutePath.isEmpty())
537 			throw new IllegalArgumentException("Argument absolutePath is empty.");
538 		if (owner == null)
539 			throw new IllegalArgumentException("Argument owner is null.");
540 		if (mode == null)
541 			throw new IllegalArgumentException("Argument mode is null.");
542 		if (lastModifiedDate == null)
543 			throw new IllegalArgumentException("Argument lastModifiedDate is null.");
544 		
545 		paths = splitAbsolutePath(absolutePath);
546 		if (paths[1].endsWith("/")) {
547 			paths[1] = paths[1].substring(0, paths[1].length() - 1);
548 		}
549 		directory = new FileMetaDataImpl(paths[0], paths[1], owner, mode, lastModifiedDate);
550 		return directory;
551 	}
552 
553 
554 	/**
555 	 * <p>
556 	 * Creates the meta data for a regular file.
557 	 * </p>
558 	 *
559 	 * @param absolutePath
560 	 *            The absolute path.
561 	 * @param owner
562 	 *            The owner of the file.
563 	 * @param mode
564 	 *            The mode of the file.
565 	 * @param length
566 	 *            The length of the file or <code>-1</code>, if the length is
567 	 *            unknown.
568 	 * @param lastModifiedDate
569 	 *            The timestamp of the last modification.
570 	 * @return The meta data.
571 	 * @throws IllegalArgumentException
572 	 *             If any of the parameters are <code>null</code>, the absolute
573 	 *             path is empty or the length is less than <code>-1</code>.
574 	 */
575 	public static FileMetaData createFileMetaData(String absolutePath, FileOwner owner, FileMode mode, long length,
576 			Date lastModifiedDate) {
577 		
578 		FileMetaData file;
579 		String[] paths;
580 
581 
582 		if (absolutePath == null)
583 			throw new IllegalArgumentException("Argument absolutePath is null.");
584 		if (absolutePath.isEmpty())
585 			throw new IllegalArgumentException("Argument absolutePath is empty.");
586 		if (owner == null)
587 			throw new IllegalArgumentException("Argument owner is null.");
588 		if (mode == null)
589 			throw new IllegalArgumentException("Argument mode is null.");
590 		if (length < -1)
591 			throw new IllegalArgumentException("Argument length is less than -1: " + length);
592 		if (lastModifiedDate == null)
593 			throw new IllegalArgumentException("Argument lastModifiedDate is null.");
594 		
595 		paths = splitAbsolutePath(absolutePath);
596 		file = new FileMetaDataImpl(paths[0], paths[1], owner, mode, length, lastModifiedDate);
597 		return file;
598 	}
599 	
600 	
601 	/**
602 	 * <p>
603 	 * Creates the meta data for a symbolic link.
604 	 * </p>
605 	 *
606 	 * @param absolutePath
607 	 *            The absolute path.
608 	 * @param targetPath
609 	 *            The target path of the symbolic link.
610 	 * @param owner
611 	 *            The owner of the symbolic link.
612 	 * @param mode
613 	 *            The mode of the symbolic link.
614 	 * @param lastModifiedDate
615 	 *            The timestamp of the last modification.
616 	 * @return The meta data.
617 	 * @throws IllegalArgumentException
618 	 *             If any of the parameters are <code>null</code>, the absolute
619 	 *             path is empty or the target is empty.
620 	 */
621 	public static FileMetaData createSymbolicLinkMetaData(String absolutePath, String targetPath, FileOwner owner,
622 			FileMode mode, Date lastModifiedDate) {
623 		
624 		FileMetaData symbolicLink;
625 		String[] paths;
626 
627 
628 		if (absolutePath == null)
629 			throw new IllegalArgumentException("Argument absolutePath is null.");
630 		if (absolutePath.isEmpty())
631 			throw new IllegalArgumentException("Argument absolutePath is empty.");
632 		if (targetPath == null)
633 			throw new IllegalArgumentException("Argument targetPath is null.");
634 		if (targetPath.isEmpty())
635 			throw new IllegalArgumentException("Argument targetPath is empty.");
636 		if (owner == null)
637 			throw new IllegalArgumentException("Argument owner is null.");
638 		if (mode == null)
639 			throw new IllegalArgumentException("Argument mode is null.");
640 		if (lastModifiedDate == null)
641 			throw new IllegalArgumentException("Argument lastModifiedDate is null.");
642 		
643 		paths = splitAbsolutePath(absolutePath);
644 		symbolicLink = new FileMetaDataImpl(paths[0], paths[1], targetPath, owner, mode, lastModifiedDate);
645 		return symbolicLink;
646 	}
647 	
648 	
649 	/**
650 	 * <p>
651 	 * Splits the absolute path into the path and the name of the file.
652 	 * </p>
653 	 *
654 	 * @param absolutePath
655 	 *            The absolute path.
656 	 * @return An array with the path as first element and the name as second
657 	 *         element.
658 	 */
659 	private static String[] splitAbsolutePath(String absolutePath) {
660 		String[] result;
661 		String value;
662 		int index;
663 
664 
665 		result = new String[2];
666 		
667 		// --- Make sure the path starts with a slash ---
668 		value = absolutePath;
669 		if (value.startsWith("./")) {
670 			value = value.substring(1);
671 		}
672 		if (!value.startsWith("/")) {
673 			value = "/" + value;
674 		}
675 		// --- Do we have the root? ---
676 		if (value.length() == 1) {
677 			result[0] = "/";
678 			result[1] = "";
679 		}
680 		// --- Otherwise split the path ---
681 		else {
682 			index = value.lastIndexOf('/');
683 			// --- Do we have a directory path? ---
684 			if (index == (value.length() - 1)) {
685 				index = value.lastIndexOf('/', index - 1);
686 			}
687 			result[0] = value.substring(0, index + 1);
688 			result[1] = value.substring(index + 1);
689 		}
690 		return result;
691 	}
692 
693 
694 }