Java 7 is now used.
[photos] / src / main / java / org / wamblee / photos / model / filesystem / FileSystemAlbum.java
index 68a8faf7499899bf4c3c48d34b7a2a70fd193a39..bfff860137c6ad68fafd4e9d3f0ec67436adc2a7 100644 (file)
@@ -22,6 +22,7 @@ import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -86,54 +87,54 @@ public class FileSystemAlbum implements Album {
     private String _path;
 
     private class CreateEntryCallback implements EntryFoundCallback {
-        public boolean photoFound(List<PhotoEntry> aEntries, File aThumbnail,
-            File aPhoto, String aPath) {
+        public boolean photoFound(List<PhotoEntry> aEntries, File aThumbnail, File aPhoto, String aPath) {
             PhotoEntry entry = new FileSystemPhoto(aThumbnail, aPhoto, aPath);
             aEntries.add(entry);
             return true;
         }
 
-        public boolean albumFound(List<PhotoEntry> aEntries, File aAlbum,
-            String aPath) throws IOException {
-            PhotoEntry entry = new FileSystemAlbum(aAlbum, aPath,
-                _entries.getCache());
+        public boolean albumFound(List<PhotoEntry> aEntries, File aAlbum, String aPath) throws IOException {
+            PhotoEntry entry = new FileSystemAlbum(aAlbum, aPath, _entries.getCache());
             aEntries.add(entry);
             return true;
         }
     }
 
+    private static final class AlbumComputation
+            implements CachedObject.Computation<String, ArrayList<PhotoEntry>>, Serializable {
+        private FileSystemAlbum album;
+
+        public AlbumComputation(FileSystemAlbum aAlbum) {
+            album = aAlbum;
+        }
+
+        @Override
+        public ArrayList<PhotoEntry> getObject(String aObjectKey) throws Exception {
+            return album.compute();
+        }
+    }
+
     /**
      * Creates the album.
-     * 
-     * @param aDir
-     *            Directory where the album is located.
-     * @param aPath
-     *            Path that this album represents.
-     * @param aCache
-     *            Cache to use.
+     *
+     * @param aDir   Directory where the album is located.
+     * @param aPath  Path that this album represents.
+     * @param aCache Cache to use.
      * @throws IOException
      */
-    public FileSystemAlbum(File aDir, String aPath,
-        Cache<String, ArrayList<PhotoEntry>> aCache) throws IOException {
+    public FileSystemAlbum(File aDir, String aPath, Cache<String, ArrayList<PhotoEntry>> aCache) throws IOException {
         if (!aDir.isDirectory()) {
             throw new IOException("Directory '" + aDir.getPath() +
-                "' does not exist.");
+                    "' does not exist.");
         }
         _dir = aDir;
         _path = aPath;
-        _entries = new CachedObject<String, ArrayList<PhotoEntry>>(aCache,
-            aPath,
-            new CachedObject.Computation<String, ArrayList<PhotoEntry>>() {
-                public ArrayList<PhotoEntry> getObject(String aObjectKey) {
-                    return FileSystemAlbum.this.compute();
-                }
-            });
-
+        _entries = new CachedObject<String, ArrayList<PhotoEntry>>(aCache, aPath, new AlbumComputation(this));
     }
 
     /**
      * Computes the photo entries for this album based on the file system.
-     * 
+     *
      * @return List of photo entries.
      */
     private ArrayList<PhotoEntry> compute() {
@@ -141,7 +142,8 @@ public class FileSystemAlbum implements Album {
         try {
             LOG.info("Initializing album for directory " + _dir);
             traverse(getPath(), result, _dir, new CreateEntryCallback());
-        } catch (IOException e) {
+        }
+        catch (IOException e) {
             LOG.fatal("IOException occurred: " + e.getMessage(), e);
         }
         return result;
@@ -149,25 +151,21 @@ public class FileSystemAlbum implements Album {
 
     /**
      * Initializes the album.
-     * 
-     * @param aPath
-     *            Path of the album
-     * @param aEntries
-     *            Photo entries for the album.
-     * @param aDir
-     *            Directory where the album is stored.
+     *
+     * @param aPath    Path of the album
+     * @param aEntries Photo entries for the album.
+     * @param aDir     Directory where the album is stored.
      * @throws IOException
      */
-    static boolean traverse(String aPath, List<PhotoEntry> aEntries, File aDir,
-        EntryFoundCallback aCallback) throws IOException {
+    static boolean traverse(String aPath, List<PhotoEntry> aEntries, File aDir, EntryFoundCallback aCallback)
+            throws IOException {
         File[] files = listFilesInDir(aDir);
         for (int i = 0; i < files.length; i++) {
             File file = files[i];
             if (file.isDirectory()) {
 
                 if (file.getName().equals(THUMBNAILS_DIR)) {
-                    if (!traverseThumbnails(aPath, aEntries, aDir, aCallback,
-                        file)) {
+                    if (!traverseThumbnails(aPath, aEntries, aDir, aCallback, file)) {
                         return false;
                     }
                 } else if (file.getName().equals(PHOTOS_DIR)) {
@@ -187,21 +185,15 @@ public class FileSystemAlbum implements Album {
 
     /**
      * Traverse the thumnails directory.
-     * 
-     * @param aPath
-     *            Path of the photo album.
-     * @param aEntries
-     *            Entries of the album.
-     * @param aDir
-     *            Directory of the album.
-     * @param aCallback
-     *            Callback to call when a thumbnail has been found.
-     * @param aFile
-     *            Directory of the photo album.
-     */
-    private static boolean traverseThumbnails(String aPath,
-        List<PhotoEntry> aEntries, File aDir, EntryFoundCallback aCallback,
-        File aFile) {
+     *
+     * @param aPath     Path of the photo album.
+     * @param aEntries  Entries of the album.
+     * @param aDir      Directory of the album.
+     * @param aCallback Callback to call when a thumbnail has been found.
+     * @param aFile     Directory of the photo album.
+     */
+    private static boolean traverseThumbnails(String aPath, List<PhotoEntry> aEntries, File aDir,
+            EntryFoundCallback aCallback, File aFile) {
         // Go inside the thumbnails directory to scan
         // for available photos.
 
@@ -214,44 +206,39 @@ public class FileSystemAlbum implements Album {
             }
         } else {
             LOG.info("Thumbnails director " + aFile.getPath() +
-                " exists but corresponding photo directory " +
-                photosDir.getPath() + " not found");
+                    " exists but corresponding photo directory " +
+                    photosDir.getPath() + " not found");
         }
         return true;
     }
 
     /**
      * Builds up the photo album for a given thumbnails and photo directory.
-     * 
-     * @param aPath
-     *            Path of the album.
-     * @param aEntries
-     *            Photo entries of the album.
-     * @param aThumbnailsDir
-     *            Directory containing thumbnail pictures.
-     * @param aPhotosDir
-     *            Directory containing full size photos.
-     */
-    private static boolean buildAlbum(String aPath, List<PhotoEntry> aEntries,
-        File aThumbnailsDir, File aPhotosDir, EntryFoundCallback aCallback) {
+     *
+     * @param aPath          Path of the album.
+     * @param aEntries       Photo entries of the album.
+     * @param aThumbnailsDir Directory containing thumbnail pictures.
+     * @param aPhotosDir     Directory containing full size photos.
+     */
+    private static boolean buildAlbum(String aPath, List<PhotoEntry> aEntries, File aThumbnailsDir, File aPhotosDir,
+            EntryFoundCallback aCallback) {
 
         File[] thumbnails = listFilesInDir(aThumbnailsDir);
         for (int i = 0; i < thumbnails.length; i++) {
             File thumbnail = thumbnails[i];
             if (!isThumbNail(thumbnail)) {
                 LOG.info("Skipping " + thumbnail.getPath() +
-                    " because it is not a thumbnail file.");
+                        " because it is not a thumbnail file.");
                 continue;
             }
             File photo = new File(aPhotosDir, photoName(thumbnail.getName()));
             if (!photo.isFile()) {
                 LOG.info("Photo file " + photo.getPath() + " for thumbnail " +
-                    thumbnail.getPath() + " does not exist.");
+                        thumbnail.getPath() + " does not exist.");
                 continue;
             }
             String photoPath = photo.getName();
-            photoPath = photoPath.substring(0, photoPath.length() -
-                JPG_EXTENSION.length());
+            photoPath = photoPath.substring(0, photoPath.length() - JPG_EXTENSION.length());
             photoPath = aPath + "/" + photoPath;
             photoPath = photoPath.replaceAll("//", "/");
             if (!aCallback.photoFound(aEntries, thumbnail, photo, photoPath)) {
@@ -272,9 +259,8 @@ public class FileSystemAlbum implements Album {
 
     /**
      * Checks if the file represents a thumbnail.
-     * 
-     * @param aFile
-     *            File to check.
+     *
+     * @param aFile File to check.
      * @return True iff the file is a thumbnail.
      */
     private static boolean isThumbNail(File aFile) {
@@ -283,15 +269,12 @@ public class FileSystemAlbum implements Album {
 
     /**
      * Constructs the photo name based on the thumbnail name.
-     * 
-     * @param aThumbnailName
-     *            Thumbnail name.
+     *
+     * @param aThumbnailName Thumbnail name.
      * @return Photo name.
      */
     private static String photoName(String aThumbnailName) {
-        return aThumbnailName.substring(0, aThumbnailName.length() -
-            THUMBNAIL_ENDING.length()) +
-            JPG_EXTENSION;
+        return aThumbnailName.substring(0, aThumbnailName.length() - THUMBNAIL_ENDING.length()) + JPG_EXTENSION;
     }
 
     /*
@@ -301,8 +284,7 @@ public class FileSystemAlbum implements Album {
      */
     public PhotoEntry getEntry(String aPath) {
         if (!aPath.startsWith("/")) {
-            throw new IllegalArgumentException(
-                "Path must start with / character");
+            throw new IllegalArgumentException("Path must start with / character");
         }
         if (aPath.equals("/")) {
             return this;
@@ -320,11 +302,9 @@ public class FileSystemAlbum implements Album {
 
     /**
      * Gets the entry at a given path.
-     * 
-     * @param aPath
-     *            Array of components of the path.
-     * @param aLevel
-     *            Current level in the path.
+     *
+     * @param aPath  Array of components of the path.
+     * @param aLevel Current level in the path.
      * @return Entry.
      */
     private PhotoEntry getEntry(String[] aPath, int aLevel) {
@@ -345,9 +325,8 @@ public class FileSystemAlbum implements Album {
 
     /**
      * Finds an entry in the album with the given id.
-     * 
-     * @param aId
-     *            Photo entry id.
+     *
+     * @param aId Photo entry id.
      * @return Photo entry.
      */
     private PhotoEntry find(String aId) {
@@ -356,9 +335,8 @@ public class FileSystemAlbum implements Album {
 
     /**
      * Finds a photo entry in the map.
-     * 
-     * @param aId
-     *            Id of the photo entry.
+     *
+     * @param aId Id of the photo entry.
      * @return Pair of a photo entry and the index of the item.
      */
     private Pair<PhotoEntry, Integer> findInMap(String aId) {
@@ -405,9 +383,8 @@ public class FileSystemAlbum implements Album {
 
     /**
      * Prints the album with a given indentation.
-     * 
-     * @param aIndent
-     *            Indentation string.
+     *
+     * @param aIndent Indentation string.
      * @return String representation of the album.
      */
     private String print(String aIndent) {
@@ -431,8 +408,7 @@ public class FileSystemAlbum implements Album {
      * @see org.wamblee.photos.database.Album#addImage(java.lang.String,
      *      java.awt.Image)
      */
-    public void addImage(String aId, InputStream aImageStream)
-        throws IOException {
+    public void addImage(String aId, InputStream aImageStream) throws IOException {
         File photoDir = getPhotoDir();
         File thumbnailDir = getThumbnailDir();
 
@@ -441,12 +417,11 @@ public class FileSystemAlbum implements Album {
         BufferedImage image;
         try {
             image = JpegUtils.loadJpegImage(aImageStream);
-        } catch (InterruptedException e) {
-            throw new IOException("Loading image interruptedS: " +
-                e.getMessage());
         }
-        BufferedImage thumbnailImage = JpegUtils.scaleImage(THUMBNAIL_WIDTH,
-            THUMBNAIL_HEIGHT, image);
+        catch (InterruptedException e) {
+            throw new IOException("Loading image interruptedS: " + e.getMessage());
+        }
+        BufferedImage thumbnailImage = JpegUtils.scaleImage(THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT, image);
 
         File thumbnail = new File(thumbnailDir, aId + THUMBNAIL_ENDING);
         File photo = new File(photoDir, aId + JPG_EXTENSION);
@@ -454,42 +429,37 @@ public class FileSystemAlbum implements Album {
         writeImage(photo, image);
         writeImage(thumbnail, thumbnailImage);
 
-        Photo photoEntry = new FileSystemPhoto(thumbnail, photo, (getPath()
-            .equals("/") ? "" : getPath()) + "/" + aId);
+        Photo photoEntry = new FileSystemPhoto(thumbnail, photo, (getPath().equals("/") ? "" : getPath()) + "/" + aId);
         addEntry(photoEntry);
     }
 
     /**
      * Checks if a given entry can be added to the album.
-     * 
-     * @param aId
-     *            Id of the new entry.
-     * @param aPhotoDir
-     *            Photo directory.
-     * @param aThumbnailDir
-     *            Thumbnail directory.
+     *
+     * @param aId           Id of the new entry.
+     * @param aPhotoDir     Photo directory.
+     * @param aThumbnailDir Thumbnail directory.
      * @throws IOException
      */
-    private void checkPhotoDirs(String aId, File aPhotoDir, File aThumbnailDir)
-        throws IOException {
+    private void checkPhotoDirs(String aId, File aPhotoDir, File aThumbnailDir) throws IOException {
         // Create directories if they do not already exist.
         aPhotoDir.mkdir();
         aThumbnailDir.mkdir();
 
         if (!aPhotoDir.isDirectory() || !aThumbnailDir.isDirectory()) {
             throw new IOException("Album " + getId() +
-                " does not accept new images.");
+                    " does not accept new images.");
         }
 
         if (getEntry("/" + aId) != null) {
             throw new IOException("An entry with the name '" + aId +
-                "' already exists in the album " + getPath());
+                    "' already exists in the album " + getPath());
         }
     }
 
     /**
      * Gets the thumbnail directory for the album.
-     * 
+     *
      * @return Directory.
      */
     private File getThumbnailDir() {
@@ -499,7 +469,7 @@ public class FileSystemAlbum implements Album {
 
     /**
      * Gets the photo directory for the album.
-     * 
+     *
      * @return Photo directory
      */
     private File getPhotoDir() {
@@ -509,17 +479,13 @@ public class FileSystemAlbum implements Album {
 
     /**
      * Writes an image to a file.
-     * 
-     * @param aFile
-     *            File to write to.
-     * @param aImage
-     *            Image.
+     *
+     * @param aFile  File to write to.
+     * @param aImage Image.
      * @throws IOException
      */
-    private static void writeImage(File aFile, BufferedImage aImage)
-        throws IOException {
-        OutputStream output = new BufferedOutputStream(new FileOutputStream(
-            aFile));
+    private static void writeImage(File aFile, BufferedImage aImage) throws IOException {
+        OutputStream output = new BufferedOutputStream(new FileOutputStream(aFile));
         JpegUtils.writeJpegImage(output, JPG_QUALITY, aImage);
         output.close();
     }
@@ -533,7 +499,7 @@ public class FileSystemAlbum implements Album {
         PhotoEntry entry = find(aId);
         if (entry != null) {
             throw new IOException("Entry already exists in album " + getId() +
-                " : " + aId);
+                    " : " + aId);
         }
         // Entry not yet found. Try to create it.
         File albumDir = new File(_dir, aId);
@@ -542,18 +508,15 @@ public class FileSystemAlbum implements Album {
         }
         File photosDir = new File(albumDir, PHOTOS_DIR);
         if (!photosDir.mkdir()) {
-            throw new IOException("Could  not create photo storage dir: " +
-                photosDir.getPath());
+            throw new IOException("Could  not create photo storage dir: " + photosDir.getPath());
         }
         File thumbnailsDir = new File(albumDir, THUMBNAILS_DIR);
         if (!thumbnailsDir.mkdir()) {
-            throw new IOException("Coul dnot create thumbnails storage dir: " +
-                thumbnailsDir.getPath());
+            throw new IOException("Coul dnot create thumbnails storage dir: " + thumbnailsDir.getPath());
         }
         String newPath = _path + "/" + aId;
         newPath = newPath.replaceAll("//", "/");
-        FileSystemAlbum album = new FileSystemAlbum(albumDir, newPath,
-            _entries.getCache());
+        FileSystemAlbum album = new FileSystemAlbum(albumDir, newPath, _entries.getCache());
         addEntry(album);
     }
 
@@ -578,9 +541,8 @@ public class FileSystemAlbum implements Album {
 
     /**
      * Removes a photo entry.
-     * 
-     * @param aEntry
-     *            Photo entry to remove.
+     *
+     * @param aEntry Photo entry to remove.
      * @throws IOException
      */
     private void removePhoto(PhotoEntry aEntry) throws IOException {
@@ -592,25 +554,21 @@ public class FileSystemAlbum implements Album {
             throw new IOException("Photo file not found: " + photo.getPath());
         }
         if (!thumbnail.isFile()) {
-            throw new IOException("Thumbnail file not found: " +
-                thumbnail.getPath());
+            throw new IOException("Thumbnail file not found: " + thumbnail.getPath());
         }
         if (!thumbnail.delete()) {
-            throw new IOException("Could not delete thumbnail file: " +
-                thumbnail.getPath());
+            throw new IOException("Could not delete thumbnail file: " + thumbnail.getPath());
         }
         _entries.get().remove(aEntry);
         if (!photo.delete()) {
-            throw new IOException("Could not delete photo file: " +
-                photo.getPath());
+            throw new IOException("Could not delete photo file: " + photo.getPath());
         }
     }
 
     /**
      * Removes the album entry from this album.
-     * 
-     * @param aAlbum
-     *            Album to remove
+     *
+     * @param aAlbum Album to remove
      * @throws IOException
      */
     private void removeAlbum(FileSystemAlbum aAlbum) throws IOException {
@@ -621,18 +579,16 @@ public class FileSystemAlbum implements Album {
         File photosDir = new File(aAlbum._dir, PHOTOS_DIR);
         File thumbnailsDir = new File(aAlbum._dir, THUMBNAILS_DIR);
         if (!photosDir.delete() || !thumbnailsDir.delete() ||
-            !aAlbum._dir.delete()) {
-            throw new IOException("Could not delete directories for album:" +
-                aAlbum.getId());
+                !aAlbum._dir.delete()) {
+            throw new IOException("Could not delete directories for album:" + aAlbum.getId());
         }
         _entries.get().remove(aAlbum);
     }
 
     /**
      * Adds an entry.
-     * 
-     * @param aEntry
-     *            Entry to add.
+     *
+     * @param aEntry Entry to add.
      */
     private void addEntry(PhotoEntry aEntry) {
         int i = 0;
@@ -674,7 +630,7 @@ public class FileSystemAlbum implements Album {
 
     /**
      * Returns and alphabetically sorted list of files.
-     * 
+     *
      * @param aDir
      * @return Sorted list of files.
      */
@@ -692,13 +648,13 @@ public class FileSystemAlbum implements Album {
         Pair<PhotoEntry, Integer> entry = findInMap(aId);
         if (entry.getFirst() == null) {
             throw new IllegalArgumentException("Entry with id '" + aId +
-                "' not found in album '" + getPath() + "'");
+                    "' not found in album '" + getPath() + "'");
         }
 
         int i = entry.getSecond() - 1;
         List<PhotoEntry> entries = _entries.get();
         while (i >= 0 && i < entries.size() &&
-            !(entries.get(i) instanceof Photo)) {
+                !(entries.get(i) instanceof Photo)) {
             i--;
         }
         if (i >= 0) {
@@ -715,12 +671,12 @@ public class FileSystemAlbum implements Album {
         Pair<PhotoEntry, Integer> entry = findInMap(aId);
         if (entry.getFirst() == null) {
             throw new IllegalArgumentException("Entry with id '" + aId +
-                "' not found in album '" + getPath() + "'");
+                    "' not found in album '" + getPath() + "'");
         }
         int i = entry.getSecond() + 1;
         List<PhotoEntry> entries = _entries.get();
         while (i >= 0 && i < entries.size() &&
-            !(entries.get(i) instanceof Photo)) {
+                !(entries.get(i) instanceof Photo)) {
             i++;
         }
         if (i < entries.size()) {