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