Code refactoring
[meviz.git] / src / main / java / eu / svjatoslav / meviz / htmlindexer / metadata / DirectoryMetadata.java
1 /*
2  * Meviz - Various tools collection to work with multimedia. Author: Svjatoslav Agejenko.
3  * This project is released under Creative Commons Zero (CC0) license.
4  */
5
6
7 package eu.svjatoslav.meviz.htmlindexer.metadata;
8
9 import eu.svjatoslav.commons.file.FilePathParser;
10 import eu.svjatoslav.meviz.htmlindexer.FileSortComparator;
11 import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.*;
12
13 import java.io.File;
14 import java.io.Serializable;
15 import java.util.*;
16
17 import static eu.svjatoslav.meviz.htmlindexer.indexer.AbstractIndexer.isImage;
18 import static eu.svjatoslav.meviz.htmlindexer.indexer.AbstractIndexer.isVideo;
19
20 /**
21  * Corresponds to single filesystem directory.
22  */
23 public class DirectoryMetadata implements Serializable {
24
25     private static final long serialVersionUID = 3526489102725366334L;
26
27     private final HashMap<String, AbstractFile> fileNameToFileMap = new HashMap<>();
28
29     public transient boolean changed;
30
31     /**
32      * Performs cleanup of directory model. In particular removes metadata for
33      * images that no longer exist in the filesystem.
34      */
35     public void cleanup() {
36         fileNameToFileMap.values().removeIf(file -> !file.isMetadataVerified());
37     }
38
39     public void ensureFileMetadataIsUpToDate(final File parentDirectory,
40                                              final File file) throws Exception {
41
42         final String fileName = file.getName();
43
44         if (fileNameToFileMap.containsKey(fileName)) {
45             final boolean metadataUpdated = fileNameToFileMap.get(fileName)
46                     .ensureFileMetadataIsUpToDate(parentDirectory);
47
48             if (metadataUpdated)
49                 changed = true;
50         } else
51             registerFile(parentDirectory, file);
52
53     }
54
55     private AbstractFile getAbstractFile(final File parentDirectory,
56                                          final File file, final String fileName) throws Exception {
57
58         if (file.isDirectory())
59             return new DirectoryFile(parentDirectory, fileName);
60
61         final String fileExtension = FilePathParser.getFileExtension(fileName)
62                 .toLowerCase();
63
64         if (isImage(fileExtension))
65             try {
66                 return new Picture(parentDirectory, fileName);
67             } catch (final Exception exception) {
68                 System.out.println("Failed to decode image \"" + fileName +"\" indexing as normal file instead.");
69
70                 // in case image decoding failed, handle image as general file
71                 return new GeneralFile(parentDirectory, fileName);
72             }
73
74         if (isVideo(fileExtension))
75             try {
76                 return new Video(parentDirectory, fileName);
77             } catch (final Exception exception) {
78                 // in case video decoding failed, handle it as general file
79                 return new GeneralFile(parentDirectory, fileName);
80             }
81
82         if (fileName.endsWith(".meviz.org"))
83             return new MevizSpecialFile(parentDirectory, fileName);
84
85         if (fileName.endsWith(".meviz.html"))
86             return new MevizSpecialFile(parentDirectory, fileName);
87
88         return new GeneralFile(parentDirectory, fileName);
89     }
90
91     private AbstractFile getFile(final String fileName) {
92         return fileNameToFileMap.get(fileName);
93     }
94
95     public Collection<AbstractFile> getFiles() {
96
97         final ArrayList<AbstractFile> files = new ArrayList<>(
98                 fileNameToFileMap.values());
99
100         files.sort(new FileSortComparator());
101
102         return files;
103     }
104
105     public String getHeaderMevizMetadataHtml() {
106         final AbstractFile headerFile = getFile("header.meviz.html");
107         if (headerFile == null)
108             return "";
109
110         final MevizSpecialFile mevizSpecialFile = (MevizSpecialFile) headerFile;
111         return mevizSpecialFile.getFileContent();
112     }
113
114     public Dimension getImageDimensions(final String fileName) {
115
116         return ((Picture) getFile(fileName)).getDimensions();
117     }
118
119     private AbstractFile registerFile(final File parentDirectory, final File file)
120             throws Exception {
121
122         final String fileName = file.getName();
123
124         final AbstractFile abstractFile = getAbstractFile(parentDirectory,
125                 file, fileName);
126
127         fileNameToFileMap.put(fileName, abstractFile);
128
129         changed = true;
130
131         return abstractFile;
132     }
133
134     public void removeUnusedMetadataEntries() {
135
136         new HashSet<>(fileNameToFileMap.keySet()).stream().filter(key -> !fileNameToFileMap.get(key).isMetadataVerified()).forEach(key -> {
137             fileNameToFileMap.remove(key);
138             changed = true;
139         });
140
141     }
142 }