Changed license to CC0.
[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         final Iterator<AbstractFile> fileIterator = fileNameToFileMap.values()
37                 .iterator();
38
39         while (fileIterator.hasNext()) {
40             final AbstractFile file = fileIterator.next();
41
42             if (!file.isMetadataVerified())
43                 fileIterator.remove();
44         }
45     }
46
47     public void ensureFileMetadataIsUpToDate(final File parentDirectory,
48                                              final File file) throws Exception {
49
50         final String fileName = file.getName();
51
52         if (fileNameToFileMap.containsKey(fileName)) {
53             final boolean metadataUpdated = fileNameToFileMap.get(fileName)
54                     .ensureFileMetadataIsUpToDate(parentDirectory);
55
56             if (metadataUpdated)
57                 changed = true;
58         } else
59             registerFile(parentDirectory, file);
60
61     }
62
63     private AbstractFile getAbstractFile(final File parentDirectory,
64                                          final File file, final String fileName) throws Exception {
65
66         if (file.isDirectory())
67             return new DirectoryFile(parentDirectory, fileName);
68
69         final String fileExtension = FilePathParser.getFileExtension(fileName)
70                 .toLowerCase();
71
72         if (isImage(fileExtension))
73             try {
74                 return new Picture(parentDirectory, fileName);
75             } catch (final Exception exception) {
76                 // in case image decoding failed, handle image as general file
77                 return new GeneralFile(parentDirectory, fileName);
78             }
79
80         if (isVideo(fileExtension))
81             try {
82                 return new Video(parentDirectory, fileName);
83             } catch (final Exception exception) {
84                 // in case video decoding failed, handle it as general file
85                 return new GeneralFile(parentDirectory, fileName);
86             }
87
88         if (fileName.endsWith(".meviz.org"))
89             return new MevizSpecialFile(parentDirectory, fileName);
90
91         if (fileName.endsWith(".meviz.html"))
92             return new MevizSpecialFile(parentDirectory, fileName);
93
94         return new GeneralFile(parentDirectory, fileName);
95     }
96
97     private AbstractFile getFile(final String fileName) {
98         return fileNameToFileMap.get(fileName);
99     }
100
101     public Collection<AbstractFile> getFiles() {
102
103         final ArrayList<AbstractFile> files = new ArrayList<>(
104                 fileNameToFileMap.values());
105
106         Collections.sort(files, new FileSortComparator());
107
108         return files;
109     }
110
111     public String getHeaderMevizMetadataHtml() {
112         final AbstractFile headerFile = getFile("header.meviz.html");
113         if (headerFile == null)
114             return "";
115
116         final MevizSpecialFile mevizSpecialFile = (MevizSpecialFile) headerFile;
117         return mevizSpecialFile.getFileContent();
118     }
119
120     public Dimension getImageDimensions(final String fileName) {
121
122         return ((Picture) getFile(fileName)).getDimensions();
123     }
124
125     private AbstractFile registerFile(final File parentDirectory, final File file)
126             throws Exception {
127
128         final String fileName = file.getName();
129
130         final AbstractFile abstractFile = getAbstractFile(parentDirectory,
131                 file, fileName);
132
133         fileNameToFileMap.put(fileName, abstractFile);
134
135         changed = true;
136
137         return abstractFile;
138     }
139
140     public void removeUnusedMetadataEntries() {
141
142         new HashSet<>(fileNameToFileMap.keySet()).stream().filter(key -> !fileNameToFileMap.get(key).isMetadataVerified()).forEach(key -> {
143             fileNameToFileMap.remove(key);
144             changed = true;
145         });
146
147     }
148 }