Code refactoring
authorSvjatoslav Agejenko <svjatoslav@svjatoslav.eu>
Sat, 19 Jan 2019 12:56:26 +0000 (14:56 +0200)
committerSvjatoslav Agejenko <svjatoslav@svjatoslav.eu>
Sat, 19 Jan 2019 12:56:26 +0000 (14:56 +0200)
17 files changed:
install
pom.xml
src/main/java/eu/svjatoslav/meviz/htmlindexer/AbstractIndexer.java [deleted file]
src/main/java/eu/svjatoslav/meviz/htmlindexer/CommandlineHandler.java
src/main/java/eu/svjatoslav/meviz/htmlindexer/FilesystemIndexRemover.java [deleted file]
src/main/java/eu/svjatoslav/meviz/htmlindexer/FilesystemIndexer.java [deleted file]
src/main/java/eu/svjatoslav/meviz/htmlindexer/Layout.java [deleted file]
src/main/java/eu/svjatoslav/meviz/htmlindexer/Main.java
src/main/java/eu/svjatoslav/meviz/htmlindexer/Utils.java
src/main/java/eu/svjatoslav/meviz/htmlindexer/WebIndexer.java [deleted file]
src/main/java/eu/svjatoslav/meviz/htmlindexer/indexer/AbstractIndexer.java [new file with mode: 0644]
src/main/java/eu/svjatoslav/meviz/htmlindexer/indexer/FilesystemIndexRemover.java [new file with mode: 0644]
src/main/java/eu/svjatoslav/meviz/htmlindexer/indexer/FilesystemIndexer.java [new file with mode: 0755]
src/main/java/eu/svjatoslav/meviz/htmlindexer/indexer/WebIndexer.java [new file with mode: 0644]
src/main/java/eu/svjatoslav/meviz/htmlindexer/layouts/Layout.java [new file with mode: 0755]
src/main/java/eu/svjatoslav/meviz/htmlindexer/layouts/MixedLayout.java
src/main/java/eu/svjatoslav/meviz/htmlindexer/metadata/DirectoryMetadata.java

diff --git a/install b/install
index 933f49d..6dc8f7f 100755 (executable)
--- a/install
+++ b/install
@@ -1,6 +1,6 @@
 #!/bin/bash
 
-sudo apt-get install maven lame vorbis-tools imagemagick ffmpeg2theora libav-tools --yes
+sudo apt-get install maven lame vorbis-tools imagemagick ffmpeg2theora --yes
 
 mvn clean
 mvn package
diff --git a/pom.xml b/pom.xml
index 02b8fda..9ad5714 100644 (file)
--- a/pom.xml
+++ b/pom.xml
                 </executions>
             </plugin>
 
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-javadoc-plugin</artifactId>
-                <version>2.9</version>
-                <executions>
-                    <execution>
-                        <id>attach-javadocs</id>
-                        <goals>
-                            <goal>jar</goal>
-                        </goals>
-                    </execution>
-                </executions>
-            </plugin>
-
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-release-plugin</artifactId>
diff --git a/src/main/java/eu/svjatoslav/meviz/htmlindexer/AbstractIndexer.java b/src/main/java/eu/svjatoslav/meviz/htmlindexer/AbstractIndexer.java
deleted file mode 100644 (file)
index 22ec825..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-package eu.svjatoslav.meviz.htmlindexer;
-
-import eu.svjatoslav.meviz.htmlindexer.metadata.Dimension;
-import eu.svjatoslav.meviz.htmlindexer.metadata.DirectoryMetadata;
-import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.*;
-
-import java.io.File;
-import java.io.UnsupportedEncodingException;
-
-import static eu.svjatoslav.meviz.htmlindexer.Constants.SUPPORTED_IMAGE_EXTENSIONS;
-import static eu.svjatoslav.meviz.htmlindexer.Constants.SUPPORTED_VIDEO_EXTENSIONS;
-
-public abstract class AbstractIndexer {
-
-    public static boolean isImage(final String fileExtension) {
-        for (final String ext : SUPPORTED_IMAGE_EXTENSIONS)
-            if (ext.equals(fileExtension))
-                return true;
-        return false;
-    }
-
-    public static boolean isVideo(final String fileExtension) {
-        for (final String ext : SUPPORTED_VIDEO_EXTENSIONS)
-            if (ext.equals(fileExtension))
-                return true;
-        return false;
-    }
-
-    static boolean shallFileBeIndexed(final File file) {
-
-        if (file.getName().startsWith("."))
-            return false;
-        if (file.getName().startsWith("index"))
-            if (file.getName().endsWith(".html"))
-                return false;
-
-        return true;
-    }
-
-    void compileHtml(final Layout layout,
-                     final DirectoryMetadata directory)
-            throws UnsupportedEncodingException {
-
-        for (final AbstractFile file : directory.getFiles())
-            if (file instanceof GeneralFile) {
-                layout.enlistFile(file, directory);
-            } else if (file instanceof Picture){
-                layout.enlistImage((Picture) file, directory);
-            } else if (file instanceof Video){
-                layout.enlistVideo((Video) file);
-            } else if (file instanceof DirectoryFile)
-                layout.enlistDirectory(file, directory);
-    }
-
-    public abstract String getDirectoryUrl(final AbstractFile directory,
-                                           IndexingContext context);
-
-    public abstract String getParentDirectoryUrl(IndexingContext context);
-
-    public abstract String getThumbnailUrl(Picture picture,
-                                           final Dimension desiredDimension, IndexingContext context);
-
-}
index 1b945c1..93a9d7b 100755 (executable)
@@ -17,7 +17,7 @@ import eu.svjatoslav.meviz.encoder.EncodingOptions;
 
 import java.io.File;
 
-class CommandlineHandler {
+public class CommandlineHandler {
 
     final Parser parser = new Parser();
     final NullParameter removeIndex = parser.add(
diff --git a/src/main/java/eu/svjatoslav/meviz/htmlindexer/FilesystemIndexRemover.java b/src/main/java/eu/svjatoslav/meviz/htmlindexer/FilesystemIndexRemover.java
deleted file mode 100644 (file)
index 30f1099..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-package eu.svjatoslav.meviz.htmlindexer;
-
-import eu.svjatoslav.commons.file.IOHelper;
-
-import java.io.File;
-import java.io.IOException;
-
-class FilesystemIndexRemover {
-
-    private final CommandlineHandler commandlineHandler;
-
-    public FilesystemIndexRemover(final CommandlineHandler commandlineHandler)
-            throws IOException {
-        this.commandlineHandler = commandlineHandler;
-
-        removeIndex(commandlineHandler.getWorkingDirectory());
-    }
-
-    private void removeIndex(final File workingDirectory) throws IOException {
-
-        // remove thumbnails directory from current directory
-        final File thumbnailsDirectory = Utils
-                .getThumbnailsDirectory(workingDirectory);
-        if (thumbnailsDirectory.exists()) {
-            System.out.println("Deleting thumbnails directory: "
-                    + thumbnailsDirectory);
-            IOHelper.deleteRecursively(thumbnailsDirectory);
-        }
-
-        // recursively remove thumbnail directories from sub directories
-        for (final File subFile : workingDirectory.listFiles())
-            if (subFile.isDirectory())
-                removeIndex(subFile);
-
-        for (final Layout layout : Utils.getLayouts()) {
-            final File indexFile = Utils.getLayoutIndexFile(layout,
-                    workingDirectory);
-
-            if (indexFile.exists())
-                if (Utils.isMevizGeneratedIndexFile(indexFile)) {
-                    System.out.println("Deleting generated index file: "
-                            + indexFile);
-                    indexFile.delete();
-                }
-        }
-
-    }
-
-}
diff --git a/src/main/java/eu/svjatoslav/meviz/htmlindexer/FilesystemIndexer.java b/src/main/java/eu/svjatoslav/meviz/htmlindexer/FilesystemIndexer.java
deleted file mode 100755 (executable)
index f001d6a..0000000
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Meviz - Various tools collection to work with multimedia.
- * Copyright (C) 2012 -- 2019, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 3 of the GNU Lesser General Public License
- * or later as published by the Free Software Foundation.
-*/
-
-package eu.svjatoslav.meviz.htmlindexer;
-
-import eu.svjatoslav.commons.file.IOHelper;
-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.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.
- */
-
-public class FilesystemIndexer extends AbstractIndexer {
-
-    private static final Logger logger = Logger
-            .getLogger(FilesystemIndexer.class);
-
-    private final HashSet<String> validMetadataFiles = new HashSet<>();
-
-    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 {
-
-        this.directoryToIndex = directoryToIndex;
-        this.commandlineHandler = commandlineHandler;
-        this.pathElements = pathElements;
-
-        if (!directoryToIndex.canRead())
-            return;
-
-        validMetadataFiles.add(Constants.METADATA_FILE_NAME);
-
-        initializeThumbnailsDirectory();
-        loadOrCreateMetadata();
-
-        initializeLayouts();
-
-        updateMetadata();
-
-        metadata.removeUnusedMetadataEntries();
-
-        generateHtmlFromMetadata(layouts);
-
-        removeUnusedThumbnailFiles();
-
-        // save directory metadata
-        if (metadata.changed)
-            MetadadaHelper.saveDirectoryMetadata(metadataFile, metadata);
-
-    }
-
-    private boolean canWriteIndexFile(final File indexFile)
-            throws IOException {
-
-        return !indexFile.exists() || Utils.isMevizGeneratedIndexFile(indexFile);
-
-    }
-
-    private void generateHtmlFromMetadata(final HashSet<Layout> layouts) {
-        // Generate HTML from metadata
-        for (final Layout layout : layouts)
-            try {
-                final File indexFile = Utils.getLayoutIndexFile(layout,
-                        directoryToIndex);
-
-                if (canWriteIndexFile(indexFile)) {
-
-                    compileHtml(layout, metadata);
-
-                    IOHelper.overwriteFileIfContentDiffers(indexFile, layout
-                            .getHtml(true, true, metadata).getBytes());
-                }
-            } catch (final Exception e) {
-                logger.error("Error writing index file. ", e);
-            }
-    }
-
-    private List<String> getChildPath(final File file) {
-
-        final List<String> result = new ArrayList<>();
-        result.addAll(pathElements);
-        result.add(file.getName());
-
-        return result;
-    }
-
-    @Override
-    public String getDirectoryUrl(final AbstractFile directory,
-                                  final IndexingContext context) {
-        return Utils.urlEncode(directory.fileName) + "/index.html";
-    }
-
-    @Override
-    public String getParentDirectoryUrl(final IndexingContext context) {
-        return "../index.html";
-    }
-
-    @Override
-    public String getThumbnailUrl(final Picture picture,
-                                  final Dimension desiredDimension, final IndexingContext context) {
-
-        // in case thumbnail size was equal to original, then return original
-        // file path
-        if (picture.getDimensions().equals(desiredDimension))
-            return picture.fileName;
-
-        final String thumbnailFileName = picture
-                .getRelativeThumbnailFileName(desiredDimension);
-
-        validMetadataFiles.add(thumbnailFileName);
-        final File thumbnailFile = new File(
-                Utils.getThumbnailsDirectoryPath(directoryToIndex)
-                        + thumbnailFileName);
-
-        if (!thumbnailFile.exists()) {
-
-            final File originalFile = new File(
-                    directoryToIndex.getAbsolutePath() + "/" + picture.fileName);
-
-            // generate new thumbnail
-            Picture.makeThumbnail(originalFile, thumbnailFile,
-                    desiredDimension.getAwtDimension());
-        }
-        return Constants.THUMBNAILS_DIRECTORY_NAME + "/"
-                + Utils.urlEncode(thumbnailFileName);
-    }
-
-    private void initializeLayouts() {
-
-        layouts = Utils.getLayouts();
-
-        final String galleryTitle = commandlineHandler.getGalleryTitle();
-
-        for (final Layout layout : layouts)
-            layout.init(galleryTitle, pathElements, this, new IndexingContext(
-                    "", "."));
-    }
-
-    private void initializeThumbnailsDirectory() {
-        final File thumbnailsDirectory = Utils
-                .getThumbnailsDirectory(directoryToIndex);
-
-        if (!thumbnailsDirectory.exists())
-            thumbnailsDirectory.mkdirs();
-    }
-
-    private void loadOrCreateMetadata() {
-
-        metadataFile = new File(
-                Utils.getThumbnailsDirectoryPath(directoryToIndex)
-                        + Constants.METADATA_FILE_NAME);
-
-        metadata = MetadadaHelper.initDirectoryMetadata(metadataFile);
-    }
-
-    private void removeUnusedThumbnailFiles() {
-
-        for (final File file : Utils.getThumbnailsDirectory(directoryToIndex)
-                .listFiles())
-            if (!validMetadataFiles.contains(file.getName()))
-                file.delete();
-
-    }
-
-    private void updateMetadata() throws Exception {
-
-        for (final File file : directoryToIndex.listFiles())
-            if (shallFileBeIndexed(file)) {
-
-                metadata.ensureFileMetadataIsUpToDate(directoryToIndex, file);
-
-                if (file.isDirectory())
-                    new FilesystemIndexer(file, commandlineHandler,
-                            getChildPath(file));
-            }
-    }
-}
diff --git a/src/main/java/eu/svjatoslav/meviz/htmlindexer/Layout.java b/src/main/java/eu/svjatoslav/meviz/htmlindexer/Layout.java
deleted file mode 100755 (executable)
index 5083b39..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Meviz - Various tools collection to work with multimedia.
- * Copyright (C) 2012 -- 2019, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 3 of the GNU Lesser General Public License
- * or later as published by the Free Software Foundation.
-*/
-
-package eu.svjatoslav.meviz.htmlindexer;
-
-import eu.svjatoslav.meviz.htmlindexer.metadata.DirectoryMetadata;
-import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.AbstractFile;
-import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.Picture;
-import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.Video;
-
-import java.util.List;
-
-/**
- * In order to have possibility of several different layouts per directory.
- * Universal interface is defined.
- * <p>
- * Layout implementation is responsible for actual HTML generation.
- */
-
-public interface Layout {
-
-    /**
-     * Enlist directory.
-     */
-    void enlistDirectory(AbstractFile directory,
-                         DirectoryMetadata parentDirectoryMetadata);
-
-    /**
-     * Enlist simple file.
-     */
-    void enlistFile(AbstractFile file,
-                    DirectoryMetadata parentDirectoryMetadata);
-
-    /**
-     * Enlist image file.
-     */
-    void enlistImage(Picture picture,
-                     DirectoryMetadata parentDirectoryMetadata);
-
-    /**
-     * Enlist video file.
-     */
-    void enlistVideo(Video file);
-
-    /**
-     * Return layout specific suffix that will be appended between
-     * index(suffix).html of generated file. This way multiple layouts can
-     * coexist in the same directory, each residing in its own HTML file.
-     */
-    String getFileNameSuffix();
-
-    /**
-     * After necessary files have been enlisted for particular directory, use
-     * this method to retrieve generated HTML result.
-     */
-    String getHtml(final boolean showTitle,
-                   final boolean doHtmlHeaderAndFooter, DirectoryMetadata metadata)
-    ;
-
-    /**
-     * Initialize layout for particular directory.
-     */
-    void init(String galleryTitle, List<String> path,
-              final AbstractIndexer indexer, IndexingContext context);
-
-}
index 6c26761..e3e1c7f 100644 (file)
@@ -1,6 +1,8 @@
 package eu.svjatoslav.meviz.htmlindexer;
 
 import eu.svjatoslav.meviz.Module;
+import eu.svjatoslav.meviz.htmlindexer.indexer.FilesystemIndexRemover;
+import eu.svjatoslav.meviz.htmlindexer.indexer.FilesystemIndexer;
 
 import java.util.ArrayList;
 
index 82c4b58..01f2d37 100755 (executable)
@@ -9,6 +9,7 @@
 
 package eu.svjatoslav.meviz.htmlindexer;
 
+import eu.svjatoslav.meviz.htmlindexer.layouts.Layout;
 import eu.svjatoslav.meviz.htmlindexer.layouts.MixedLayout;
 
 import java.awt.image.BufferedImage;
diff --git a/src/main/java/eu/svjatoslav/meviz/htmlindexer/WebIndexer.java b/src/main/java/eu/svjatoslav/meviz/htmlindexer/WebIndexer.java
deleted file mode 100644 (file)
index d2aabcd..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-package eu.svjatoslav.meviz.htmlindexer;
-
-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.fileTypes.AbstractFile;
-import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.Picture;
-
-import java.io.BufferedInputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.UnsupportedEncodingException;
-import java.net.URL;
-import java.util.List;
-
-public class WebIndexer extends AbstractIndexer {
-
-    private static final int METADATA_LOAD_TRY_COUNT = 10;
-    private final String globalPrefix;
-    private final String jspPath;
-
-    public WebIndexer(final String globalPrefix, final String jspPath) {
-        this.globalPrefix = globalPrefix;
-        this.jspPath = jspPath;
-    }
-
-    @Override
-    public void compileHtml(final Layout layout,
-                            final DirectoryMetadata directory)
-            throws UnsupportedEncodingException {
-        super.compileHtml(layout, directory);
-    }
-
-    @Override
-    public String getDirectoryUrl(final AbstractFile directory,
-                                  final IndexingContext context) {
-        return jspPath + context.getLocalUrl() + "/" + directory.fileName;
-    }
-
-    public String getHtml(String requestPath) throws
-            IOException, ClassNotFoundException {
-
-        if (requestPath == null)
-            requestPath = "";
-
-        if (requestPath.equals("/"))
-            requestPath = "";
-
-        final MixedLayout layout = new MixedLayout();
-        final IndexingContext context = new IndexingContext(globalPrefix,
-                requestPath);
-        layout.init("Photos", context.getLocalPathComponents(), this, context);
-
-        final DirectoryMetadata directory = getMetadataForPath(requestPath);
-
-        compileHtml(layout, directory);
-
-        return layout.getHtml(false, false, directory);
-    }
-
-    private DirectoryMetadata getMetadataForPath(final String requestPath)
-            throws ClassNotFoundException, IOException {
-
-        final String urlString = globalPrefix + Utils.urlEncode(requestPath) + "/.thumbnails/metadata_6.dat";
-
-        for (int i = 0; true; i++)
-            try {
-                return attemptDirectoryMetadataDownload(urlString);
-            } catch (final IOException e) {
-                if (i > METADATA_LOAD_TRY_COUNT) throw e;
-            }
-    }
-
-    private DirectoryMetadata attemptDirectoryMetadataDownload(String urlString) throws IOException, ClassNotFoundException {
-        final BufferedInputStream inputStream = new BufferedInputStream(new URL(
-                urlString).openStream());
-
-        final ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
-        final DirectoryMetadata directory = (DirectoryMetadata) objectInputStream
-                .readObject();
-        inputStream.close();
-
-        return directory;
-    }
-
-    @Override
-    public String getParentDirectoryUrl(final IndexingContext context) {
-        final StringBuilder result = new StringBuilder();
-
-        result.append(jspPath);
-
-        final List<String> components = context.getLocalPathComponents();
-
-        for (final String pathComponent : components.subList(0,
-                components.size() - 1)) {
-            result.append("/");
-            result.append(pathComponent);
-        }
-
-        return result.toString();
-    }
-
-    @Override
-    public String getThumbnailUrl(final Picture picture,
-                                  final Dimension desiredDimension, final IndexingContext context) {
-
-        // in case thumbnail size was equal to original, then return original
-        // file path
-        if (picture.getDimensions().equals(desiredDimension))
-            return context.getGlobalUrl() + context.getLocalUrl() + "/"
-                    + picture.fileName;
-
-        final String thumbnailFileName = picture
-                .getRelativeThumbnailFileName(desiredDimension);
-
-        return context.getGlobalUrl() + context.getLocalUrl() + "/"
-                + Constants.THUMBNAILS_DIRECTORY_NAME + "/"
-                + Utils.urlEncode(thumbnailFileName);
-    }
-
-}
diff --git a/src/main/java/eu/svjatoslav/meviz/htmlindexer/indexer/AbstractIndexer.java b/src/main/java/eu/svjatoslav/meviz/htmlindexer/indexer/AbstractIndexer.java
new file mode 100644 (file)
index 0000000..0329989
--- /dev/null
@@ -0,0 +1,65 @@
+package eu.svjatoslav.meviz.htmlindexer.indexer;
+
+import eu.svjatoslav.meviz.htmlindexer.IndexingContext;
+import eu.svjatoslav.meviz.htmlindexer.layouts.Layout;
+import eu.svjatoslav.meviz.htmlindexer.metadata.Dimension;
+import eu.svjatoslav.meviz.htmlindexer.metadata.DirectoryMetadata;
+import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.*;
+
+import java.io.File;
+import java.io.UnsupportedEncodingException;
+
+import static eu.svjatoslav.meviz.htmlindexer.Constants.SUPPORTED_IMAGE_EXTENSIONS;
+import static eu.svjatoslav.meviz.htmlindexer.Constants.SUPPORTED_VIDEO_EXTENSIONS;
+
+public abstract class AbstractIndexer {
+
+    public static boolean isImage(final String fileExtension) {
+        for (final String ext : SUPPORTED_IMAGE_EXTENSIONS)
+            if (ext.equals(fileExtension))
+                return true;
+        return false;
+    }
+
+    public static boolean isVideo(final String fileExtension) {
+        for (final String ext : SUPPORTED_VIDEO_EXTENSIONS)
+            if (ext.equals(fileExtension))
+                return true;
+        return false;
+    }
+
+    static boolean shallFileBeIndexed(final File file) {
+
+        if (file.getName().startsWith("."))
+            return false;
+        if (file.getName().startsWith("index"))
+            if (file.getName().endsWith(".html"))
+                return false;
+
+        return true;
+    }
+
+    void compileHtml(final Layout layout,
+                     final DirectoryMetadata directory)
+            throws UnsupportedEncodingException {
+
+        for (final AbstractFile file : directory.getFiles())
+            if (file instanceof GeneralFile) {
+                layout.enlistFile(file, directory);
+            } else if (file instanceof Picture){
+                layout.enlistImage((Picture) file, directory);
+            } else if (file instanceof Video){
+                layout.enlistVideo((Video) file);
+            } else if (file instanceof DirectoryFile)
+                layout.enlistDirectory(file, directory);
+    }
+
+    public abstract String getDirectoryUrl(final AbstractFile directory,
+                                           IndexingContext context);
+
+    public abstract String getParentDirectoryUrl(IndexingContext context);
+
+    public abstract String getThumbnailUrl(Picture picture,
+                                           final Dimension desiredDimension, IndexingContext context);
+
+}
diff --git a/src/main/java/eu/svjatoslav/meviz/htmlindexer/indexer/FilesystemIndexRemover.java b/src/main/java/eu/svjatoslav/meviz/htmlindexer/indexer/FilesystemIndexRemover.java
new file mode 100644 (file)
index 0000000..9023697
--- /dev/null
@@ -0,0 +1,52 @@
+package eu.svjatoslav.meviz.htmlindexer.indexer;
+
+import eu.svjatoslav.commons.file.IOHelper;
+import eu.svjatoslav.meviz.htmlindexer.CommandlineHandler;
+import eu.svjatoslav.meviz.htmlindexer.layouts.Layout;
+import eu.svjatoslav.meviz.htmlindexer.Utils;
+
+import java.io.File;
+import java.io.IOException;
+
+public class FilesystemIndexRemover {
+
+    private final CommandlineHandler commandlineHandler;
+
+    public FilesystemIndexRemover(final CommandlineHandler commandlineHandler)
+            throws IOException {
+        this.commandlineHandler = commandlineHandler;
+
+        removeIndex(commandlineHandler.getWorkingDirectory());
+    }
+
+    private void removeIndex(final File workingDirectory) throws IOException {
+
+        // remove thumbnails directory from current directory
+        final File thumbnailsDirectory = Utils
+                .getThumbnailsDirectory(workingDirectory);
+        if (thumbnailsDirectory.exists()) {
+            System.out.println("Deleting thumbnails directory: "
+                    + thumbnailsDirectory);
+            IOHelper.deleteRecursively(thumbnailsDirectory);
+        }
+
+        // recursively remove thumbnail directories from sub directories
+        for (final File subFile : workingDirectory.listFiles())
+            if (subFile.isDirectory())
+                removeIndex(subFile);
+
+        for (final Layout layout : Utils.getLayouts()) {
+            final File indexFile = Utils.getLayoutIndexFile(layout,
+                    workingDirectory);
+
+            if (indexFile.exists())
+                if (Utils.isMevizGeneratedIndexFile(indexFile)) {
+                    System.out.println("Deleting generated index file: "
+                            + indexFile);
+                    indexFile.delete();
+                }
+        }
+
+    }
+
+}
diff --git a/src/main/java/eu/svjatoslav/meviz/htmlindexer/indexer/FilesystemIndexer.java b/src/main/java/eu/svjatoslav/meviz/htmlindexer/indexer/FilesystemIndexer.java
new file mode 100755 (executable)
index 0000000..6add6be
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012 -- 2019, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 3 of the GNU Lesser General Public License
+ * or later as published by the Free Software Foundation.
+*/
+
+package eu.svjatoslav.meviz.htmlindexer.indexer;
+
+import eu.svjatoslav.commons.file.IOHelper;
+import eu.svjatoslav.meviz.htmlindexer.*;
+import eu.svjatoslav.meviz.htmlindexer.layouts.Layout;
+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.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.
+ */
+
+public class FilesystemIndexer extends AbstractIndexer {
+
+    private static final Logger logger = Logger
+            .getLogger(FilesystemIndexer.class);
+
+    private final HashSet<String> validMetadataFiles = new HashSet<>();
+
+    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 {
+
+        this.directoryToIndex = directoryToIndex;
+        this.commandlineHandler = commandlineHandler;
+        this.pathElements = pathElements;
+
+        if (!directoryToIndex.canRead())
+            return;
+
+        validMetadataFiles.add(Constants.METADATA_FILE_NAME);
+
+        initializeThumbnailsDirectory();
+        loadOrCreateMetadata();
+
+        initializeLayouts();
+
+        updateMetadata();
+
+        metadata.removeUnusedMetadataEntries();
+
+        generateHtmlFromMetadata(layouts);
+
+        removeUnusedThumbnailFiles();
+
+        // save directory metadata
+        if (metadata.changed)
+            MetadadaHelper.saveDirectoryMetadata(metadataFile, metadata);
+
+    }
+
+    private boolean canWriteIndexFile(final File indexFile)
+            throws IOException {
+
+        return !indexFile.exists() || Utils.isMevizGeneratedIndexFile(indexFile);
+
+    }
+
+    private void generateHtmlFromMetadata(final HashSet<Layout> layouts) {
+        // Generate HTML from metadata
+        for (final Layout layout : layouts)
+            try {
+                final File indexFile = Utils.getLayoutIndexFile(layout,
+                        directoryToIndex);
+
+                if (canWriteIndexFile(indexFile)) {
+
+                    compileHtml(layout, metadata);
+
+                    IOHelper.overwriteFileIfContentDiffers(indexFile, layout
+                            .getHtml(true, true, metadata).getBytes());
+                }
+            } catch (final Exception e) {
+                logger.error("Error writing index file. ", e);
+            }
+    }
+
+    private List<String> getChildPath(final File file) {
+
+        final List<String> result = new ArrayList<>();
+        result.addAll(pathElements);
+        result.add(file.getName());
+
+        return result;
+    }
+
+    @Override
+    public String getDirectoryUrl(final AbstractFile directory,
+                                  final IndexingContext context) {
+        return Utils.urlEncode(directory.fileName) + "/index.html";
+    }
+
+    @Override
+    public String getParentDirectoryUrl(final IndexingContext context) {
+        return "../index.html";
+    }
+
+    @Override
+    public String getThumbnailUrl(final Picture picture,
+                                  final Dimension desiredDimension, final IndexingContext context) {
+
+        // in case thumbnail size was equal to original, then return original
+        // file path
+        if (picture.getDimensions().equals(desiredDimension))
+            return picture.fileName;
+
+        final String thumbnailFileName = picture
+                .getRelativeThumbnailFileName(desiredDimension);
+
+        validMetadataFiles.add(thumbnailFileName);
+        final File thumbnailFile = new File(
+                Utils.getThumbnailsDirectoryPath(directoryToIndex)
+                        + thumbnailFileName);
+
+        if (!thumbnailFile.exists()) {
+
+            final File originalFile = new File(
+                    directoryToIndex.getAbsolutePath() + "/" + picture.fileName);
+
+            // generate new thumbnail
+            Picture.makeThumbnail(originalFile, thumbnailFile,
+                    desiredDimension.getAwtDimension());
+        }
+        return Constants.THUMBNAILS_DIRECTORY_NAME + "/"
+                + Utils.urlEncode(thumbnailFileName);
+    }
+
+    private void initializeLayouts() {
+
+        layouts = Utils.getLayouts();
+
+        final String galleryTitle = commandlineHandler.getGalleryTitle();
+
+        for (final Layout layout : layouts)
+            layout.init(galleryTitle, pathElements, this, new IndexingContext(
+                    "", "."));
+    }
+
+    private void initializeThumbnailsDirectory() {
+        final File thumbnailsDirectory = Utils
+                .getThumbnailsDirectory(directoryToIndex);
+
+        if (!thumbnailsDirectory.exists())
+            thumbnailsDirectory.mkdirs();
+    }
+
+    private void loadOrCreateMetadata() {
+
+        metadataFile = new File(
+                Utils.getThumbnailsDirectoryPath(directoryToIndex)
+                        + Constants.METADATA_FILE_NAME);
+
+        metadata = MetadadaHelper.initDirectoryMetadata(metadataFile);
+    }
+
+    private void removeUnusedThumbnailFiles() {
+
+        for (final File file : Utils.getThumbnailsDirectory(directoryToIndex)
+                .listFiles())
+            if (!validMetadataFiles.contains(file.getName()))
+                file.delete();
+
+    }
+
+    private void updateMetadata() throws Exception {
+
+        for (final File file : directoryToIndex.listFiles())
+            if (shallFileBeIndexed(file)) {
+
+                metadata.ensureFileMetadataIsUpToDate(directoryToIndex, file);
+
+                if (file.isDirectory())
+                    new FilesystemIndexer(file, commandlineHandler,
+                            getChildPath(file));
+            }
+    }
+}
diff --git a/src/main/java/eu/svjatoslav/meviz/htmlindexer/indexer/WebIndexer.java b/src/main/java/eu/svjatoslav/meviz/htmlindexer/indexer/WebIndexer.java
new file mode 100644 (file)
index 0000000..966d10f
--- /dev/null
@@ -0,0 +1,125 @@
+package eu.svjatoslav.meviz.htmlindexer.indexer;
+
+import eu.svjatoslav.meviz.htmlindexer.Constants;
+import eu.svjatoslav.meviz.htmlindexer.IndexingContext;
+import eu.svjatoslav.meviz.htmlindexer.layouts.Layout;
+import eu.svjatoslav.meviz.htmlindexer.Utils;
+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.fileTypes.AbstractFile;
+import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.Picture;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URL;
+import java.util.List;
+
+public class WebIndexer extends AbstractIndexer {
+
+    private static final int METADATA_LOAD_TRY_COUNT = 10;
+    private final String globalPrefix;
+    private final String jspPath;
+
+    public WebIndexer(final String globalPrefix, final String jspPath) {
+        this.globalPrefix = globalPrefix;
+        this.jspPath = jspPath;
+    }
+
+    @Override
+    public void compileHtml(final Layout layout,
+                            final DirectoryMetadata directory)
+            throws UnsupportedEncodingException {
+        super.compileHtml(layout, directory);
+    }
+
+    @Override
+    public String getDirectoryUrl(final AbstractFile directory,
+                                  final IndexingContext context) {
+        return jspPath + context.getLocalUrl() + "/" + directory.fileName;
+    }
+
+    public String getHtml(String requestPath) throws
+            IOException, ClassNotFoundException {
+
+        if (requestPath == null)
+            requestPath = "";
+
+        if (requestPath.equals("/"))
+            requestPath = "";
+
+        final MixedLayout layout = new MixedLayout();
+        final IndexingContext context = new IndexingContext(globalPrefix,
+                requestPath);
+        layout.init("Photos", context.getLocalPathComponents(), this, context);
+
+        final DirectoryMetadata directory = getMetadataForPath(requestPath);
+
+        compileHtml(layout, directory);
+
+        return layout.getHtml(false, false, directory);
+    }
+
+    private DirectoryMetadata getMetadataForPath(final String requestPath)
+            throws ClassNotFoundException, IOException {
+
+        final String urlString = globalPrefix + Utils.urlEncode(requestPath) + "/.thumbnails/metadata_6.dat";
+
+        for (int i = 0; true; i++)
+            try {
+                return attemptDirectoryMetadataDownload(urlString);
+            } catch (final IOException e) {
+                if (i > METADATA_LOAD_TRY_COUNT) throw e;
+            }
+    }
+
+    private DirectoryMetadata attemptDirectoryMetadataDownload(String urlString) throws IOException, ClassNotFoundException {
+        final BufferedInputStream inputStream = new BufferedInputStream(new URL(
+                urlString).openStream());
+
+        final ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
+        final DirectoryMetadata directory = (DirectoryMetadata) objectInputStream
+                .readObject();
+        inputStream.close();
+
+        return directory;
+    }
+
+    @Override
+    public String getParentDirectoryUrl(final IndexingContext context) {
+        final StringBuilder result = new StringBuilder();
+
+        result.append(jspPath);
+
+        final List<String> components = context.getLocalPathComponents();
+
+        for (final String pathComponent : components.subList(0,
+                components.size() - 1)) {
+            result.append("/");
+            result.append(pathComponent);
+        }
+
+        return result.toString();
+    }
+
+    @Override
+    public String getThumbnailUrl(final Picture picture,
+                                  final Dimension desiredDimension, final IndexingContext context) {
+
+        // in case thumbnail size was equal to original, then return original
+        // file path
+        if (picture.getDimensions().equals(desiredDimension))
+            return context.getGlobalUrl() + context.getLocalUrl() + "/"
+                    + picture.fileName;
+
+        final String thumbnailFileName = picture
+                .getRelativeThumbnailFileName(desiredDimension);
+
+        return context.getGlobalUrl() + context.getLocalUrl() + "/"
+                + Constants.THUMBNAILS_DIRECTORY_NAME + "/"
+                + Utils.urlEncode(thumbnailFileName);
+    }
+
+}
diff --git a/src/main/java/eu/svjatoslav/meviz/htmlindexer/layouts/Layout.java b/src/main/java/eu/svjatoslav/meviz/htmlindexer/layouts/Layout.java
new file mode 100755 (executable)
index 0000000..ef250e5
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Meviz - Various tools collection to work with multimedia.
+ * Copyright (C) 2012 -- 2019, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 3 of the GNU Lesser General Public License
+ * or later as published by the Free Software Foundation.
+*/
+
+package eu.svjatoslav.meviz.htmlindexer.layouts;
+
+import eu.svjatoslav.meviz.htmlindexer.IndexingContext;
+import eu.svjatoslav.meviz.htmlindexer.indexer.AbstractIndexer;
+import eu.svjatoslav.meviz.htmlindexer.metadata.DirectoryMetadata;
+import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.AbstractFile;
+import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.Picture;
+import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.Video;
+
+import java.util.List;
+
+/**
+ * In order to have possibility of several different layouts per directory.
+ * Universal interface is defined.
+ * <p>
+ * Layout implementation is responsible for actual HTML generation.
+ */
+
+public interface Layout {
+
+    /**
+     * Enlist directory.
+     */
+    void enlistDirectory(AbstractFile directory,
+                         DirectoryMetadata parentDirectoryMetadata);
+
+    /**
+     * Enlist simple file.
+     */
+    void enlistFile(AbstractFile file,
+                    DirectoryMetadata parentDirectoryMetadata);
+
+    /**
+     * Enlist image file.
+     */
+    void enlistImage(Picture picture,
+                     DirectoryMetadata parentDirectoryMetadata);
+
+    /**
+     * Enlist video file.
+     */
+    void enlistVideo(Video file);
+
+    /**
+     * Return layout specific suffix that will be appended between
+     * index(suffix).html of generated file. This way multiple layouts can
+     * coexist in the same directory, each residing in its own HTML file.
+     */
+    String getFileNameSuffix();
+
+    /**
+     * After necessary files have been enlisted for particular directory, use
+     * this method to retrieve generated HTML result.
+     */
+    String getHtml(final boolean showTitle,
+                   final boolean doHtmlHeaderAndFooter, DirectoryMetadata metadata)
+    ;
+
+    /**
+     * Initialize layout for particular directory.
+     */
+    void init(String galleryTitle, List<String> path,
+              final AbstractIndexer indexer, IndexingContext context);
+
+}
index 13aaff3..49ffa7e 100755 (executable)
 package eu.svjatoslav.meviz.htmlindexer.layouts;
 
 import eu.svjatoslav.commons.file.FilePathParser;
-import eu.svjatoslav.meviz.htmlindexer.AbstractIndexer;
+import eu.svjatoslav.meviz.htmlindexer.indexer.AbstractIndexer;
 import eu.svjatoslav.meviz.htmlindexer.Constants;
 import eu.svjatoslav.meviz.htmlindexer.IndexingContext;
-import eu.svjatoslav.meviz.htmlindexer.Layout;
 import eu.svjatoslav.meviz.htmlindexer.metadata.Dimension;
 import eu.svjatoslav.meviz.htmlindexer.metadata.DirectoryMetadata;
 import eu.svjatoslav.meviz.htmlindexer.metadata.fileTypes.AbstractFile;
index ec10f90..f165694 100755 (executable)
@@ -17,8 +17,8 @@ import java.io.File;
 import java.io.Serializable;
 import java.util.*;
 
-import static eu.svjatoslav.meviz.htmlindexer.AbstractIndexer.isImage;
-import static eu.svjatoslav.meviz.htmlindexer.AbstractIndexer.isVideo;
+import static eu.svjatoslav.meviz.htmlindexer.indexer.AbstractIndexer.isImage;
+import static eu.svjatoslav.meviz.htmlindexer.indexer.AbstractIndexer.isVideo;
 
 /**
  * Corresponds to single filesystem directory.