better sorting of directories

This commit is contained in:
Erik Forkalsrud 2009-05-03 17:38:35 -07:00
parent 7386a1a36e
commit 0a7867cf14
4 changed files with 233 additions and 191 deletions

View file

@ -44,8 +44,8 @@ public class ComparatorFactory {
public int compare(Entry e1, Entry e2) {
Date d1 = e1.getDate();
Date d2 = e2.getDate();
Date d1 = e1.getEarliest();
Date d2 = e2.getEarliest();
if (d1 != null && d2 != null) {
return d1.compareTo(d2);
} else if (d1 != null) {

View file

@ -19,6 +19,7 @@ import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.imageio.ImageIO;
@ -46,6 +47,7 @@ public class DirectoryEntry extends Entry {
List<Entry> children = new ArrayList<Entry>();
boolean childrenLoaded = false;
Comparator<Entry> sort = null;
Date earliest = null;
public DirectoryEntry(File file) {
super(file);
@ -137,7 +139,7 @@ public class DirectoryEntry extends Entry {
return props;
}
Properties generateCache() throws MetadataException, JpegProcessingException, IOException {
Properties generateCache() throws MetadataException, JpegProcessingException, IOException, ParseException {
long start = System.currentTimeMillis();
Properties props = new Properties();
@ -151,8 +153,9 @@ public class DirectoryEntry extends Entry {
void generateFileEntries(Properties props)
throws IOException, MetadataException, JpegProcessingException {
throws IOException, MetadataException, JpegProcessingException, ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HHmmss");
File[] files = file.listFiles();
for (File f : files) {
@ -174,7 +177,11 @@ public class DirectoryEntry extends Entry {
continue;
}
if (name.endsWith(".jpg") || name.endsWith(".jpeg") || name.endsWith(".JPG")) {
generateThumbnailProperties(props, f);
String base = "file." + f.getName() + ".";
Map<String, String> p = generateThumbnailProperties(f);
for (Map.Entry<String, String> e : p.entrySet()) {
props.setProperty(base + e.getKey(), e.getValue());
}
}
}
}
@ -186,10 +193,10 @@ public class DirectoryEntry extends Entry {
props.setProperty("dir." + name, "present");
}
private void generateThumbnailProperties(Properties props, File f)
private Map<String, String> generateThumbnailProperties(File f)
throws JpegProcessingException, MetadataException, IOException {
HashMap<String, String> props = new HashMap<String, String>();
String name = f.getName();
String base = "file." + name + ".";
boolean hasDate = false;
boolean hasOrientation = false;
boolean hasDim = false;
@ -202,52 +209,53 @@ public class DirectoryEntry extends Entry {
Directory exifDirectory = metadata.getDirectory(ExifDirectory.class);
if (exifDirectory.containsTag(ExifDirectory.TAG_ORIENTATION)) {
int orientation = exifDirectory.getInt(ExifDirectory.TAG_ORIENTATION);
props.setProperty(base + "orientation", nf.format(orientation));
props.put("orientation", nf.format(orientation));
hasOrientation = true;
}
if (exifDirectory.containsTag(ExifDirectory.TAG_EXIF_IMAGE_WIDTH) &&
exifDirectory.containsTag(ExifDirectory.TAG_EXIF_IMAGE_HEIGHT)) {
int width = exifDirectory.getInt(ExifDirectory.TAG_EXIF_IMAGE_WIDTH);
int height = exifDirectory.getInt(ExifDirectory.TAG_EXIF_IMAGE_HEIGHT);
props.setProperty(base + "dimensions", new Dimension(width, height).toString());
props.put("dimensions", new Dimension(width, height).toString());
hasDim = true;
}
if (exifDirectory.containsTag(ExifDirectory.TAG_DATETIME_ORIGINAL)) {
Date captureDate = getExifDate(exifDirectory, ExifDirectory.TAG_DATETIME_ORIGINAL);
if (captureDate != null) {
props.setProperty(base + "captureDate", sdf.format(captureDate));
props.put("captureDate", sdf.format(captureDate));
hasDate = true;
}
}
if (exifDirectory.containsTag(ExifDirectory.TAG_USER_COMMENT)) {
String comment = exifDirectory.getString(ExifDirectory.TAG_USER_COMMENT);
props.setProperty(base + "comment", comment);
props.put("comment", comment);
}
Directory jpegDirectory = metadata.getDirectory(JpegDirectory.class);
if (jpegDirectory.containsTag(JpegDirectory.TAG_JPEG_IMAGE_WIDTH) &&
jpegDirectory.containsTag(JpegDirectory.TAG_JPEG_IMAGE_HEIGHT)) {
int width = jpegDirectory.getInt(JpegDirectory.TAG_JPEG_IMAGE_WIDTH);
int height = jpegDirectory.getInt(JpegDirectory.TAG_JPEG_IMAGE_HEIGHT);
props.setProperty(base + "dimensions", new Dimension(width, height).toString());
props.put("dimensions", new Dimension(width, height).toString());
hasDim = true;
}
} catch (Exception e) {
throw new RuntimeException("problem reading file " + f.getPath(), e);
}
props.setProperty(base + "etag", Integer.toHexString(name.hashCode() + Long.valueOf(f.lastModified()).hashCode()));
props.put("etag", Integer.toHexString(name.hashCode() + Long.valueOf(f.lastModified()).hashCode()));
if (!hasDate) {
props.setProperty(base + "captureDate", sdf.format(new Date(f.lastModified())));
props.put("captureDate", sdf.format(new Date(f.lastModified())));
}
if (!hasOrientation) {
props.setProperty(base + "orientation", "1");
props.put("orientation", "1");
}
if (!hasDim) {
Dimension dim = decodeImageForDimensions(f);
if (dim != null) {
props.setProperty(base + "dimensions", dim.toString());
props.put("dimensions", dim.toString());
hasDim = true;
}
}
return props;
}
private Date getExifDate(Directory exifDirectory, int tagName) throws MetadataException {
@ -305,9 +313,13 @@ public class DirectoryEntry extends Entry {
String caption = props.getProperty("caption");
setCaption(caption);
sort = ComparatorFactory.getSort(props.getProperty("sort"));
HashMap<String, Entry> entryMap = new HashMap<String, Entry>();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HHmmss");
Iterator i = props.keySet().iterator();
Date oldest = new Date(file.lastModified());
Iterator<Object> i = props.keySet().iterator();
while (i.hasNext()) {
String key = (String)i.next();
if (key.startsWith("file.") && key.endsWith(".dimensions")) {
@ -317,7 +329,11 @@ public class DirectoryEntry extends Entry {
FileEntry entry = new FileEntry(this, f);
Thumbnail thumbnail = new Thumbnail(f);
entry.setCaption(props.getProperty("file." + name + ".caption"));
entry.setDate(sdf.parse(props.getProperty("file." + name + ".captureDate")));
Date fileDate = sdf.parse(props.getProperty("file." + name + ".captureDate"));
if (fileDate.before(oldest)) {
oldest = fileDate;
}
entry.setDate(fileDate);
thumbnail.setSize(new Dimension(props.getProperty("file." + name + ".dimensions")));
thumbnail.setOrientation(Integer.parseInt(props.getProperty("file." + name + ".orientation")));
thumbnail.setEtag(props.getProperty("file." + name + ".etag"));
@ -334,13 +350,26 @@ public class DirectoryEntry extends Entry {
String name = key.substring("dir.".length());
boolean hidden = Boolean.parseBoolean(props.getProperty("dir." + name + ".hidden"));
if (!hidden) {
children.add(new DirectoryEntry(this, new File(file, name)));
DirectoryEntry dir = new DirectoryEntry(this, new File(file, name));
children.add(dir);
Date fileDate = dir.getEarliest();
if (fileDate != null && fileDate.before(oldest)) {
oldest = fileDate;
}
}
}
}
this.earliest = oldest;
if (thumbnail == null && !children.isEmpty()) {
setThumbnail(children.get(0).getThumbnail());
}
}
@Override
public Date getEarliest() {
loadChildren();
return earliest;
}
}

View file

@ -100,4 +100,8 @@ public abstract class Entry {
public File getPath() {
return file;
}
public Date getEarliest() {
return getDate();
}
}

View file

@ -2,6 +2,8 @@ package org.forkalsrud.album.web;
import java.io.File;
import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.TimeoutException;
import javax.servlet.RequestDispatcher;
@ -230,7 +232,6 @@ public class AlbumServlet
public class Mapper {
public String map(File file) {
StringBuilder buf = new StringBuilder();
return appendFile(buf, file).toString();
}
@ -245,7 +246,15 @@ public class AlbumServlet
return appendFile(buf, file.getParentFile()).append('/').append(file.getName());
}
}
Calendar cal = Calendar.getInstance();
public String year(Date d) {
cal.setTime(d);
return String.valueOf(cal.get(Calendar.YEAR));
}
}
}
// eof