Adding workaround for exif arser bug
Support for customized sort of directory entry contents
This commit is contained in:
parent
e29fb43972
commit
600201a52d
4 changed files with 181 additions and 27 deletions
BIN
photos/geiranger/91860001.jpg
Executable file
BIN
photos/geiranger/91860001.jpg
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 3.5 MiB |
126
src/org/forkalsrud/album/exif/ComparatorFactory.java
Normal file
126
src/org/forkalsrud/album/exif/ComparatorFactory.java
Normal file
|
|
@ -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<Entry> directoryFirst = new Comparator<Entry>() {
|
||||||
|
|
||||||
|
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<Entry> dates = new Comparator<Entry>() {
|
||||||
|
|
||||||
|
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<Entry> names = new Comparator<Entry>() {
|
||||||
|
|
||||||
|
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<String, Comparator<Entry>> map = new HashMap<String, Comparator<Entry>>();
|
||||||
|
|
||||||
|
public ComparatorFactory() {
|
||||||
|
|
||||||
|
map.put(DIR, directoryFirst);
|
||||||
|
map.put(DATE, dates);
|
||||||
|
map.put(NAME, names);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Comparator<T> reverse(final Comparator<T> c) {
|
||||||
|
|
||||||
|
return new Comparator<T>() {
|
||||||
|
|
||||||
|
public int compare(T o1, T o2) {
|
||||||
|
return c.compare(o2, o1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public Comparator<Entry> getComparator(String sortSpec) {
|
||||||
|
|
||||||
|
Matcher m = SORT_SPEC_SYNTAX.matcher(sortSpec);
|
||||||
|
int start = 0;
|
||||||
|
ArrayList<Comparator<Entry>> list = new ArrayList<Comparator<Entry>>();
|
||||||
|
while (m.find(start)) {
|
||||||
|
|
||||||
|
String param = m.group(1);
|
||||||
|
String direction = m.group(3);
|
||||||
|
Comparator<Entry> 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<Entry>(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Comparator<Entry> getSort(String sortSpec) {
|
||||||
|
|
||||||
|
return singleton.getComparator(sortSpec != null ? sortSpec : "dir, date");
|
||||||
|
}
|
||||||
|
}
|
||||||
32
src/org/forkalsrud/album/exif/ComposingComparator.java
Normal file
32
src/org/forkalsrud/album/exif/ComposingComparator.java
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.forkalsrud.album.exif;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author knut
|
||||||
|
*/
|
||||||
|
public class ComposingComparator<T> implements Comparator<T> {
|
||||||
|
|
||||||
|
List<Comparator<T>> cmp;
|
||||||
|
|
||||||
|
public ComposingComparator(List<Comparator<T>> args) {
|
||||||
|
|
||||||
|
cmp = args;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int compare(T o1, T o2) {
|
||||||
|
|
||||||
|
for (Comparator<T> c : cmp) {
|
||||||
|
int result = c.compare(o1, o2);
|
||||||
|
if (result != 0) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -45,6 +45,7 @@ public class DirectoryEntry extends Entry {
|
||||||
File cache;
|
File cache;
|
||||||
List<Entry> children = new ArrayList<Entry>();
|
List<Entry> children = new ArrayList<Entry>();
|
||||||
boolean childrenLoaded = false;
|
boolean childrenLoaded = false;
|
||||||
|
Comparator<Entry> sort = null;
|
||||||
|
|
||||||
public DirectoryEntry(File file) {
|
public DirectoryEntry(File file) {
|
||||||
super(file);
|
super(file);
|
||||||
|
|
@ -138,9 +139,13 @@ public class DirectoryEntry extends Entry {
|
||||||
|
|
||||||
Properties generateCache() throws MetadataException, JpegProcessingException, IOException {
|
Properties generateCache() throws MetadataException, JpegProcessingException, IOException {
|
||||||
|
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
Properties props = new Properties();
|
Properties props = new Properties();
|
||||||
generateFileEntries(props);
|
generateFileEntries(props);
|
||||||
props.store(new FileOutputStream(cache), "Extra Comments");
|
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;
|
return props;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -206,9 +211,11 @@ public class DirectoryEntry extends Entry {
|
||||||
hasDim = true;
|
hasDim = true;
|
||||||
}
|
}
|
||||||
if (exifDirectory.containsTag(ExifDirectory.TAG_DATETIME_ORIGINAL)) {
|
if (exifDirectory.containsTag(ExifDirectory.TAG_DATETIME_ORIGINAL)) {
|
||||||
Date captureDate = exifDirectory.getDate(ExifDirectory.TAG_DATETIME_ORIGINAL);
|
Date captureDate = getExifDate(exifDirectory, ExifDirectory.TAG_DATETIME_ORIGINAL);
|
||||||
props.setProperty(base + "captureDate", sdf.format(captureDate));
|
if (captureDate != null) {
|
||||||
hasDate = true;
|
props.setProperty(base + "captureDate", sdf.format(captureDate));
|
||||||
|
hasDate = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (exifDirectory.containsTag(ExifDirectory.TAG_USER_COMMENT)) {
|
if (exifDirectory.containsTag(ExifDirectory.TAG_USER_COMMENT)) {
|
||||||
String comment = exifDirectory.getString(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 suffix = null;
|
||||||
String name = file.getName();
|
String name = file.getName();
|
||||||
|
|
@ -259,28 +275,7 @@ public class DirectoryEntry extends Entry {
|
||||||
|
|
||||||
private void sort() {
|
private void sort() {
|
||||||
|
|
||||||
Collections.sort(children, new Comparator<Entry>() {
|
Collections.sort(children, sort);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void fillLinkedList() {
|
void fillLinkedList() {
|
||||||
|
|
@ -304,6 +299,7 @@ public class DirectoryEntry extends Entry {
|
||||||
String coverFileName = props.getProperty("cover");
|
String coverFileName = props.getProperty("cover");
|
||||||
String caption = props.getProperty("caption");
|
String caption = props.getProperty("caption");
|
||||||
setCaption(caption);
|
setCaption(caption);
|
||||||
|
sort = ComparatorFactory.getSort(props.getProperty("sort"));
|
||||||
HashMap<String, Entry> entryMap = new HashMap<String, Entry>();
|
HashMap<String, Entry> entryMap = new HashMap<String, Entry>();
|
||||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HHmmss");
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HHmmss");
|
||||||
Iterator i = props.keySet().iterator();
|
Iterator i = props.keySet().iterator();
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue