Updated copyright message.
[meviz.git] / src / main / java / eu / svjatoslav / meviz / htmlindexer / FilesystemIndexer.java
index 4e1b2f2..48ed951 100755 (executable)
@@ -1,7 +1,7 @@
 /*
  * Meviz - Various tools collection to work with multimedia.
- * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
- * 
+ * Copyright (C) 2012 -- 2018, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of version 2 of the GNU General Public License
  * as published by the Free Software Foundation.
@@ -9,28 +9,19 @@
 
 package eu.svjatoslav.meviz.htmlindexer;
 
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-
-import org.apache.log4j.Logger;
-
 import eu.svjatoslav.commons.file.IOHelper;
-import eu.svjatoslav.commons.network.UrlParamEncoder;
-import eu.svjatoslav.meviz.htmlindexer.layouts.MixedLayout;
 import eu.svjatoslav.meviz.htmlindexer.metadata.Dimension;
 import eu.svjatoslav.meviz.htmlindexer.metadata.DirectoryMetadata;
 import eu.svjatoslav.meviz.htmlindexer.metadata.MetadadaHelper;
 import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.AbstractFile;
-import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.DirectoryFile;
-import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.GeneralFile;
 import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.Picture;
+import org.apache.log4j.Logger;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
 
 /**
  * Main class of HTML indexer.
@@ -38,234 +29,173 @@ import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.Picture;
 
 public class FilesystemIndexer extends AbstractIndexer {
 
-       public static final Logger logger = Logger
-                       .getLogger(FilesystemIndexer.class);
-
-       private final HashSet<String> validMetadataFiles = new HashSet<String>();
-
-       private final File directoryToIndex;
-
-       private String thumbnailsPath;
-
-       private File metadataFile;
-
-       private DirectoryMetadata metadata;
-
-       private final IndexingOptions indexingOptions;
-
-       private final List<String> pathElements;
-
-       private HashSet<Layout> layouts;
-
-       public FilesystemIndexer(final File directoryToIndex,
-                       final IndexingOptions indexingOptions,
-                       final List<String> pathElements) throws IOException,
-                       ImageFormatError {
-
-               this.directoryToIndex = directoryToIndex;
-               this.indexingOptions = indexingOptions;
-               this.pathElements = pathElements;
-
-               if (!directoryToIndex.canRead())
-                       return;
-
-               validMetadataFiles.add(Constants.METADATA_FILE_NAME);
-
-               initializeThumbnailsDirectory();
-               loadOrCreateMetadata();
-
-               initializeLayouts();
-
-               updateMetadata();
-
-               metadata.removeUnusedMetadataEntries();
-
-               generateHtmlFromMetadata(layouts);
+    private static final Logger logger = Logger
+            .getLogger(FilesystemIndexer.class);
 
-               removeUnusedThumbnailFiles();
+    private final HashSet<String> validMetadataFiles = new HashSet<>();
 
-               // save directory metadata
-               if (metadata.changed)
-                       MetadadaHelper.saveDirectoryMetadata(metadataFile, metadata);
+    private final File directoryToIndex;
+    private final List<String> pathElements;
+    private final CommandlineHandler commandlineHandler;
+    private File metadataFile;
+    private DirectoryMetadata metadata;
+    private HashSet<Layout> layouts;
 
-       }
+    public FilesystemIndexer(final File directoryToIndex,
+                             final CommandlineHandler commandlineHandler,
+                             final List<String> pathElements) throws Exception {
 
-       public boolean canWriteIndexFile(final File indexFile)
-                       throws FileNotFoundException, IOException {
-               boolean canWriteIndexFile = false;
+        this.directoryToIndex = directoryToIndex;
+        this.commandlineHandler = commandlineHandler;
+        this.pathElements = pathElements;
 
-               if (indexFile.exists()) {
-                       // if file already exists, make sure that we can overwrite
-                       // it
-                       final FileReader fileReader = new FileReader(indexFile);
-                       final BufferedReader reader = new BufferedReader(fileReader);
+        if (!directoryToIndex.canRead())
+            return;
 
-                       parseFile: {
-                               while (true) {
-                                       final String line = reader.readLine();
+        validMetadataFiles.add(Constants.METADATA_FILE_NAME);
 
-                                       if (line == null)
-                                               break parseFile;
+        initializeThumbnailsDirectory();
+        loadOrCreateMetadata();
 
-                                       if (line.contains(Constants.HTML_MAGIC_STRING)) {
-                                               canWriteIndexFile = true;
-                                               break parseFile;
-                                       }
-                               }
-                       }
+        initializeLayouts();
 
-                       reader.close();
-                       fileReader.close();
-               } else
-                       canWriteIndexFile = true;
-               return canWriteIndexFile;
-       }
+        updateMetadata();
 
-       public void cleanupUnusedMetadataFiles() {
-               final File thumbnailsDirectory = new File(thumbnailsPath);
+        metadata.removeUnusedMetadataEntries();
 
-               for (final File file : thumbnailsDirectory.listFiles())
-                       if (!validMetadataFiles.contains(file.getName()))
-                               file.delete();
-       }
+        generateHtmlFromMetadata(layouts);
 
-       public void generateHtmlFromMetadata(final HashSet<Layout> layouts) {
-               // Generate HTML from metadata
-               for (final Layout layout : layouts) {
+        removeUnusedThumbnailFiles();
 
-                       final String indexFilePath = directoryToIndex.getAbsolutePath()
-                                       + "/index" + layout.getFileNameSuffix() + ".html";
+        // save directory metadata
+        if (metadata.changed)
+            MetadadaHelper.saveDirectoryMetadata(metadataFile, metadata);
 
-                       try {
+    }
 
-                               final File indexFile = new File(indexFilePath);
-                               if (canWriteIndexFile(indexFile)) {
+    private boolean canWriteIndexFile(final File indexFile)
+            throws IOException {
 
-                                       indexForLayout(layout);
+        return !indexFile.exists() || Utils.isMevizGeneratedIndexFile(indexFile);
 
-                                       IOHelper.overwriteFileIfContentDiffers(indexFile, layout
-                                                       .getHtml(true, true).getBytes());
-                               }
-                       } catch (final Exception e) {
-                               logger.error("Error writing index file to:" + indexFilePath, e);
-                       }
-               }
-       }
+    }
 
-       public List<String> getChildPath(final File file) {
+    private void generateHtmlFromMetadata(final HashSet<Layout> layouts) {
+        // Generate HTML from metadata
+        for (final Layout layout : layouts)
+            try {
+                final File indexFile = Utils.getLayoutIndexFile(layout,
+                        directoryToIndex);
 
-               final List<String> result = new ArrayList<String>();
-               result.addAll(pathElements);
-               result.add(file.getName());
+                if (canWriteIndexFile(indexFile)) {
 
-               return result;
-       }
+                    compileHtml(layout, metadata);
 
-       @Override
-       public String getDirectoryUrl(final AbstractFile directory,
-                       final IndexingContext context) {
-               return directory.fileName + "/index.html";
-       }
+                    IOHelper.overwriteFileIfContentDiffers(indexFile, layout
+                            .getHtml(true, true, metadata).getBytes());
+                }
+            } catch (final Exception e) {
+                logger.error("Error writing index file. ", e);
+            }
+    }
 
-       @Override
-       public String getParentDirectoryUrl(final IndexingContext context) {
-               return "../index.html";
-       }
+    private List<String> getChildPath(final File file) {
 
-       @Override
-       public String getThumbnailUrl(final Picture picture,
-                       final Dimension desiredDimension, final IndexingContext context) {
+        final List<String> result = new ArrayList<>();
+        result.addAll(pathElements);
+        result.add(file.getName());
 
-               // in case thumbnail size was equal to original, then return original
-               // file path
-               if (picture.getDimensions().equals(desiredDimension))
-                       return picture.fileName;
+        return result;
+    }
 
-               final String thumbnailFileName = picture
-                               .getRelativeThumbnailFileName(desiredDimension);
+    @Override
+    public String getDirectoryUrl(final AbstractFile directory,
+                                  final IndexingContext context) {
+        return Utils.urlEncode(directory.fileName) + "/index.html";
+    }
 
-               validMetadataFiles.add(thumbnailFileName);
-               final File thumbnailFile = new File(thumbnailsPath + thumbnailFileName);
+    @Override
+    public String getParentDirectoryUrl(final IndexingContext context) {
+        return "../index.html";
+    }
 
-               if (!thumbnailFile.exists()) {
+    @Override
+    public String getThumbnailUrl(final Picture picture,
+                                  final Dimension desiredDimension, final IndexingContext context) {
 
-                       final File originalFile = new File(
-                                       directoryToIndex.getAbsolutePath() + "/" + picture.fileName);
+        // in case thumbnail size was equal to original, then return original
+        // file path
+        if (picture.getDimensions().equals(desiredDimension))
+            return picture.fileName;
 
-                       // generate new thumbnail
-                       Picture.makeThumbnail(originalFile, thumbnailFile,
-                                       desiredDimension.getAwtDimension());
-               }
-               return Constants.THUMBNAILS_DIRECTORY_NAME + "/"
-                               + UrlParamEncoder.encode(thumbnailFileName);
-       }
+        final String thumbnailFileName = picture
+                .getRelativeThumbnailFileName(desiredDimension);
 
-       public void indexForLayout(final Layout layout)
-                       throws UnsupportedEncodingException {
+        validMetadataFiles.add(thumbnailFileName);
+        final File thumbnailFile = new File(
+                Utils.getThumbnailsDirectoryPath(directoryToIndex)
+                        + thumbnailFileName);
 
-               for (final AbstractFile abstractFile : metadata.getFiles())
-                       if (abstractFile instanceof GeneralFile) {
+        if (!thumbnailFile.exists()) {
 
-                               if (isOgv(abstractFile.getFileExtension()))
-                                       layout.enlistOgv(abstractFile);
-                               else
-                                       layout.enlistFile(abstractFile);
+            final File originalFile = new File(
+                    directoryToIndex.getAbsolutePath() + "/" + picture.fileName);
 
-                       } else if (abstractFile instanceof Picture)
-                               layout.enlistImage(abstractFile);
-                       else if (abstractFile instanceof DirectoryFile)
-                               layout.enlistDirectory(abstractFile);
+            // generate new thumbnail
+            Picture.makeThumbnail(originalFile, thumbnailFile,
+                    desiredDimension.getAwtDimension());
+        }
+        return Constants.THUMBNAILS_DIRECTORY_NAME + "/"
+                + Utils.urlEncode(thumbnailFileName);
+    }
 
-       }
+    private void initializeLayouts() {
 
-       public void initializeLayouts() {
-               layouts = new HashSet<Layout>();
-               layouts.add(new MixedLayout());
+        layouts = Utils.getLayouts();
 
-               for (final Layout layout : layouts)
-                       layout.init(indexingOptions.galleryTitle, pathElements, this,
-                                       new IndexingContext("", ""));
-       }
+        final String galleryTitle = commandlineHandler.getGalleryTitle();
 
-       public void initializeThumbnailsDirectory() {
-               // initialize thumbnails directory
-               thumbnailsPath = directoryToIndex.getAbsolutePath() + "/"
-                               + Constants.THUMBNAILS_DIRECTORY_NAME + "/";
+        for (final Layout layout : layouts)
+            layout.init(galleryTitle, pathElements, this, new IndexingContext(
+                    "", "."));
+    }
 
-               // ensure thumbnails directory exists
-               final File thumbnailsDirectory = new File(thumbnailsPath);
-               if (!thumbnailsDirectory.exists())
-                       thumbnailsDirectory.mkdirs();
-       }
+    private void initializeThumbnailsDirectory() {
+        final File thumbnailsDirectory = Utils
+                .getThumbnailsDirectory(directoryToIndex);
 
-       public void loadOrCreateMetadata() {
-               metadataFile = new File(thumbnailsPath + Constants.METADATA_FILE_NAME);
+        if (!thumbnailsDirectory.exists())
+            thumbnailsDirectory.mkdirs();
+    }
 
-               metadata = MetadadaHelper.initDirectoryMetadata(metadataFile);
-       }
+    private void loadOrCreateMetadata() {
 
-       private void removeUnusedThumbnailFiles() {
+        metadataFile = new File(
+                Utils.getThumbnailsDirectoryPath(directoryToIndex)
+                        + Constants.METADATA_FILE_NAME);
 
-               final File thumbnailsDirectory = new File(thumbnailsPath);
+        metadata = MetadadaHelper.initDirectoryMetadata(metadataFile);
+    }
 
-               for (final File file : thumbnailsDirectory.listFiles())
-                       if (!validMetadataFiles.contains(file.getName()))
-                               file.delete();
+    private void removeUnusedThumbnailFiles() {
 
-       }
+        for (final File file : Utils.getThumbnailsDirectory(directoryToIndex)
+                .listFiles())
+            if (!validMetadataFiles.contains(file.getName()))
+                file.delete();
 
-       public void updateMetadata() throws IOException, ImageFormatError {
+    }
 
-               final File[] directoryContent = directoryToIndex.listFiles();
+    private void updateMetadata() throws Exception {
 
-               for (final File file : directoryContent)
-                       if (shallFileBeIndexed(file)) {
+        for (final File file : directoryToIndex.listFiles())
+            if (shallFileBeIndexed(file)) {
 
-                               metadata.ensureFileMetainfoIsUpToDate(directoryToIndex, file);
+                metadata.ensureFileMetainfoIsUpToDate(directoryToIndex, file);
 
-                               if (file.isDirectory())
-                                       new FilesystemIndexer(file, indexingOptions,
-                                                       getChildPath(file));
-                       }
-       }
+                if (file.isDirectory())
+                    new FilesystemIndexer(file, commandlineHandler,
+                            getChildPath(file));
+            }
+    }
 }