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;
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() {
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;
/**
* 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)) {
/**
* 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.
}
} 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)) {
/**
* 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) {
/**
* 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;
}
/*
*/
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;
/**
* 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) {
/**
* 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) {
/**
* 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) {
/**
* 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) {
* @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();
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);
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() {
/**
* Gets the photo directory for the album.
- *
+ *
* @return Photo directory
*/
private File getPhotoDir() {
/**
* 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();
}
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);
}
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);
}
/**
* 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 {
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 {
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;
/**
* Returns and alphabetically sorted list of files.
- *
+ *
* @param aDir
* @return Sorted list of files.
*/
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) {
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()) {