diff --git a/photos/geiranger/91860001.jpg b/photos/geiranger/91860001.jpg new file mode 100755 index 0000000..d8e3282 Binary files /dev/null and b/photos/geiranger/91860001.jpg differ diff --git a/src/org/forkalsrud/album/exif/ComparatorFactory.java b/src/org/forkalsrud/album/exif/ComparatorFactory.java new file mode 100644 index 0000000..ae90621 --- /dev/null +++ b/src/org/forkalsrud/album/exif/ComparatorFactory.java @@ -0,0 +1,126 @@ +/** + * + */ +package org.forkalsrud.album.exif; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @author knut + * + */ +public class ComparatorFactory { + + public static final String ASC = "asc"; + public static final String DESC = "desc"; + public static final String DIR = "dir"; + public static final String DATE = "date"; + public static final String NAME = "name"; + + static Pattern SORT_SPEC_SYNTAX = Pattern.compile("(\\w+)(\\s+(" + ASC + "|" + DESC + "))?,? *"); + + static ComparatorFactory singleton = new ComparatorFactory(); + + Comparator directoryFirst = new Comparator() { + + public int compare(Entry e1, Entry e2) { + + if (!e1.isFile() && e2.isFile()) { + return -1; + } else if (e1.isFile() && !e2.isFile()) { + return +1; + } + return 0; + } + }; + + + Comparator dates = new Comparator() { + + public int compare(Entry e1, Entry e2) { + + Date d1 = e1.getDate(); + Date d2 = e2.getDate(); + if (d1 != null && d2 != null) { + return d1.compareTo(d2); + } else if (d1 != null) { + return -1; + } else if (d2 != null) { + return +1; + } else { + return 0; + } + } + }; + + Comparator names = new Comparator() { + + public int compare(Entry e1, Entry e2) { + + String n1 = e1.getName(); + String n2 = e2.getName(); + if (n1 != null && n2 != null) { + return n1.compareTo(n2); + } else if (n1 != null) { + return -1; + } else if (n2 != null) { + return +1; + } else { + return 0; + } + } + }; + + HashMap> map = new HashMap>(); + + public ComparatorFactory() { + + map.put(DIR, directoryFirst); + map.put(DATE, dates); + map.put(NAME, names); + } + + public static Comparator reverse(final Comparator c) { + + return new Comparator() { + + public int compare(T o1, T o2) { + return c.compare(o2, o1); + } + }; + } + + + + public Comparator getComparator(String sortSpec) { + + Matcher m = SORT_SPEC_SYNTAX.matcher(sortSpec); + int start = 0; + ArrayList> list = new ArrayList>(); + while (m.find(start)) { + + String param = m.group(1); + String direction = m.group(3); + Comparator c = map.get(param); + if (c == null) { + throw new IllegalArgumentException(param); + } + if (DESC.equals(direction)) { + c = reverse(c); + } + list.add(c); + start = m.end(); + } + return new ComposingComparator(list); + } + + public static Comparator getSort(String sortSpec) { + + return singleton.getComparator(sortSpec != null ? sortSpec : "dir, date"); + } +} \ No newline at end of file diff --git a/src/org/forkalsrud/album/exif/ComposingComparator.java b/src/org/forkalsrud/album/exif/ComposingComparator.java new file mode 100644 index 0000000..cf40b38 --- /dev/null +++ b/src/org/forkalsrud/album/exif/ComposingComparator.java @@ -0,0 +1,32 @@ +/** + * + */ +package org.forkalsrud.album.exif; + +import java.util.Comparator; +import java.util.List; + +/** + * @author knut + */ +public class ComposingComparator implements Comparator { + + List> cmp; + + public ComposingComparator(List> args) { + + cmp = args; + } + + public int compare(T o1, T o2) { + + for (Comparator c : cmp) { + int result = c.compare(o1, o2); + if (result != 0) { + return result; + } + } + return 0; + } + +} diff --git a/src/org/forkalsrud/album/exif/DirectoryEntry.java b/src/org/forkalsrud/album/exif/DirectoryEntry.java index b8e235a..17c8dd7 100644 --- a/src/org/forkalsrud/album/exif/DirectoryEntry.java +++ b/src/org/forkalsrud/album/exif/DirectoryEntry.java @@ -45,6 +45,7 @@ public class DirectoryEntry extends Entry { File cache; List children = new ArrayList(); boolean childrenLoaded = false; + Comparator sort = null; public DirectoryEntry(File file) { super(file); @@ -137,10 +138,14 @@ public class DirectoryEntry extends Entry { } Properties generateCache() throws MetadataException, JpegProcessingException, IOException { - + + long start = System.currentTimeMillis(); Properties props = new Properties(); generateFileEntries(props); props.store(new FileOutputStream(cache), "Extra Comments"); + long end = System.currentTimeMillis(); + System.out.println("Time to generate properties for " + file.getPath() + ": " + (end - start)/1000d + " s"); + return props; } @@ -206,9 +211,11 @@ public class DirectoryEntry extends Entry { hasDim = true; } if (exifDirectory.containsTag(ExifDirectory.TAG_DATETIME_ORIGINAL)) { - Date captureDate = exifDirectory.getDate(ExifDirectory.TAG_DATETIME_ORIGINAL); - props.setProperty(base + "captureDate", sdf.format(captureDate)); - hasDate = true; + Date captureDate = getExifDate(exifDirectory, ExifDirectory.TAG_DATETIME_ORIGINAL); + if (captureDate != null) { + props.setProperty(base + "captureDate", sdf.format(captureDate)); + hasDate = true; + } } if (exifDirectory.containsTag(ExifDirectory.TAG_USER_COMMENT)) { String comment = exifDirectory.getString(ExifDirectory.TAG_USER_COMMENT); @@ -238,7 +245,16 @@ public class DirectoryEntry extends Entry { } } - Dimension decodeImageForDimensions(File file) throws IOException { + private Date getExifDate(Directory exifDirectory, int tagName) throws MetadataException { + + String dateStr = (String)exifDirectory.getObject(tagName); + if (" : : : : ".equals(dateStr)) { + return null; + } + return exifDirectory.getDate(tagName); + } + + Dimension decodeImageForDimensions(File file) throws IOException { String suffix = null; String name = file.getName(); @@ -259,28 +275,7 @@ public class DirectoryEntry extends Entry { private void sort() { - Collections.sort(children, new Comparator() { - - public int compare(Entry e1, Entry e2) { - - if (!e1.isFile() && e2.isFile()) { - return -1; - } else if (e1.isFile() && !e2.isFile()) { - return +1; - } - Date d1 = e1.getDate(); - Date d2 = e2.getDate(); - if (d1 != null && d2 != null) { - return d1.compareTo(d2); - } else if (d1 != null) { - return -1; - } else if (d2 != null) { - return +1; - } else { - return 0; - } - } - }); + Collections.sort(children, sort); } void fillLinkedList() { @@ -304,6 +299,7 @@ public class DirectoryEntry extends Entry { String coverFileName = props.getProperty("cover"); String caption = props.getProperty("caption"); setCaption(caption); + sort = ComparatorFactory.getSort(props.getProperty("sort")); HashMap entryMap = new HashMap(); SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HHmmss"); Iterator i = props.keySet().iterator();