better sorting of directories
This commit is contained in:
parent
7386a1a36e
commit
0a7867cf14
4 changed files with 233 additions and 191 deletions
|
|
@ -44,8 +44,8 @@ public class ComparatorFactory {
|
||||||
|
|
||||||
public int compare(Entry e1, Entry e2) {
|
public int compare(Entry e1, Entry e2) {
|
||||||
|
|
||||||
Date d1 = e1.getDate();
|
Date d1 = e1.getEarliest();
|
||||||
Date d2 = e2.getDate();
|
Date d2 = e2.getEarliest();
|
||||||
if (d1 != null && d2 != null) {
|
if (d1 != null && d2 != null) {
|
||||||
return d1.compareTo(d2);
|
return d1.compareTo(d2);
|
||||||
} else if (d1 != null) {
|
} else if (d1 != null) {
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
|
|
@ -43,223 +44,230 @@ public class DirectoryEntry extends Entry {
|
||||||
final static String OVERRIDE_FILE = "album.properties";
|
final static String OVERRIDE_FILE = "album.properties";
|
||||||
|
|
||||||
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;
|
Comparator<Entry> sort = null;
|
||||||
|
Date earliest = null;
|
||||||
|
|
||||||
public DirectoryEntry(File file) {
|
public DirectoryEntry(File file) {
|
||||||
super(file);
|
super(file);
|
||||||
if (!file.isDirectory()) {
|
if (!file.isDirectory()) {
|
||||||
throw new RuntimeException("Use DirectoryEntry only for directories: " + file);
|
throw new RuntimeException("Use DirectoryEntry only for directories: " + file);
|
||||||
}
|
}
|
||||||
cache = new File(file, CACHE_FILE);
|
cache = new File(file, CACHE_FILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DirectoryEntry(Entry parent, File file) {
|
public DirectoryEntry(Entry parent, File file) {
|
||||||
this(file);
|
this(file);
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static Entry getEntry(File f) {
|
public static Entry getEntry(File f) {
|
||||||
return new DirectoryEntry(f.getParentFile()).get(f);
|
return new DirectoryEntry(f.getParentFile()).get(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isFile() {
|
public boolean isFile() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Entry> getContents() {
|
public List<Entry> getContents() {
|
||||||
|
|
||||||
loadChildren();
|
loadChildren();
|
||||||
return children;
|
return children;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Thumbnail getThumbnail() {
|
public Thumbnail getThumbnail() {
|
||||||
loadChildren();
|
loadChildren();
|
||||||
return super.getThumbnail();
|
return super.getThumbnail();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getCaption() {
|
public String getCaption() {
|
||||||
loadChildren();
|
loadChildren();
|
||||||
return super.getCaption();
|
return super.getCaption();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addContents(Entry entry) {
|
public void addContents(Entry entry) {
|
||||||
children.add(entry);
|
children.add(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Entry get(File f) {
|
public Entry get(File f) {
|
||||||
loadChildren();
|
loadChildren();
|
||||||
for (Entry e : children) {
|
for (Entry e : children) {
|
||||||
if (f.equals(e.file)) {
|
if (f.equals(e.file)) {
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void loadChildren() {
|
protected void loadChildren() {
|
||||||
|
|
||||||
if (childrenLoaded) {
|
if (childrenLoaded) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
Properties cachedProps = isCacheCurrent() ? loadFromFile(cache) : generateCache();
|
Properties cachedProps = isCacheCurrent() ? loadFromFile(cache) : generateCache();
|
||||||
Properties combined = new Properties();
|
Properties combined = new Properties();
|
||||||
combined.putAll(cachedProps);
|
combined.putAll(cachedProps);
|
||||||
File override = new File(file, OVERRIDE_FILE);
|
File override = new File(file, OVERRIDE_FILE);
|
||||||
if (override.exists() && override.isFile() && override.canRead()) {
|
if (override.exists() && override.isFile() && override.canRead()) {
|
||||||
Properties overrideProps = loadFromFile(override);
|
Properties overrideProps = loadFromFile(override);
|
||||||
combined.putAll(overrideProps);
|
combined.putAll(overrideProps);
|
||||||
}
|
}
|
||||||
populate(combined);
|
populate(combined);
|
||||||
sort();
|
sort();
|
||||||
fillLinkedList();
|
fillLinkedList();
|
||||||
childrenLoaded = true;
|
childrenLoaded = true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isCacheCurrent() {
|
boolean isCacheCurrent() {
|
||||||
return cache.exists() && cache.isFile() && cache.canRead() && file.lastModified() <= cache.lastModified();
|
return cache.exists() && cache.isFile() && cache.canRead() && file.lastModified() <= cache.lastModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
Properties loadFromFile(File propFile) throws IOException {
|
Properties loadFromFile(File propFile) throws IOException {
|
||||||
|
|
||||||
Properties props = new Properties();
|
Properties props = new Properties();
|
||||||
props.load(new FileInputStream(propFile));
|
props.load(new FileInputStream(propFile));
|
||||||
return props;
|
return props;
|
||||||
}
|
}
|
||||||
|
|
||||||
Properties generateCache() throws MetadataException, JpegProcessingException, IOException {
|
Properties generateCache() throws MetadataException, JpegProcessingException, IOException, ParseException {
|
||||||
|
|
||||||
long start = System.currentTimeMillis();
|
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();
|
long end = System.currentTimeMillis();
|
||||||
System.out.println("Time to generate properties for " + file.getPath() + ": " + (end - start)/1000d + " s");
|
System.out.println("Time to generate properties for " + file.getPath() + ": " + (end - start)/1000d + " s");
|
||||||
|
|
||||||
return props;
|
return props;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void generateFileEntries(Properties props)
|
void generateFileEntries(Properties props)
|
||||||
throws IOException, MetadataException, JpegProcessingException {
|
throws IOException, MetadataException, JpegProcessingException, ParseException {
|
||||||
|
|
||||||
File[] files = file.listFiles();
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HHmmss");
|
||||||
for (File f : files) {
|
File[] files = file.listFiles();
|
||||||
|
for (File f : files) {
|
||||||
|
|
||||||
String name = f.getName();
|
String name = f.getName();
|
||||||
if (f.isDirectory()) {
|
if (f.isDirectory()) {
|
||||||
if ("CVS".equals(name)) {
|
if ("CVS".equals(name)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (f.isHidden()) {
|
if (f.isHidden()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
generateDirectoryProperties(props, f);
|
generateDirectoryProperties(props, f);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (file.isHidden()) {
|
if (file.isHidden()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (CACHE_FILE.equals(name) || OVERRIDE_FILE.equals(name)) {
|
if (CACHE_FILE.equals(name) || OVERRIDE_FILE.equals(name)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (name.endsWith(".jpg") || name.endsWith(".jpeg") || name.endsWith(".JPG")) {
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void generateDirectoryProperties(Properties props, File f) {
|
private void generateDirectoryProperties(Properties props, File f) {
|
||||||
|
|
||||||
String name = f.getName();
|
String name = f.getName();
|
||||||
props.setProperty("dir." + name, "present");
|
props.setProperty("dir." + name, "present");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateThumbnailProperties(Properties props, File f)
|
private Map<String, String> generateThumbnailProperties(File f)
|
||||||
throws JpegProcessingException, MetadataException, IOException {
|
throws JpegProcessingException, MetadataException, IOException {
|
||||||
String name = f.getName();
|
HashMap<String, String> props = new HashMap<String, String>();
|
||||||
String base = "file." + name + ".";
|
String name = f.getName();
|
||||||
boolean hasDate = false;
|
boolean hasDate = false;
|
||||||
boolean hasOrientation = false;
|
boolean hasOrientation = false;
|
||||||
boolean hasDim = false;
|
boolean hasDim = false;
|
||||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HHmmss");
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HHmmss");
|
||||||
NumberFormat nf = new DecimalFormat("0");
|
NumberFormat nf = new DecimalFormat("0");
|
||||||
|
|
||||||
Metadata metadata;
|
Metadata metadata;
|
||||||
try {
|
try {
|
||||||
metadata = JpegMetadataReader.readMetadata(f);
|
metadata = JpegMetadataReader.readMetadata(f);
|
||||||
Directory exifDirectory = metadata.getDirectory(ExifDirectory.class);
|
Directory exifDirectory = metadata.getDirectory(ExifDirectory.class);
|
||||||
if (exifDirectory.containsTag(ExifDirectory.TAG_ORIENTATION)) {
|
if (exifDirectory.containsTag(ExifDirectory.TAG_ORIENTATION)) {
|
||||||
int orientation = exifDirectory.getInt(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;
|
hasOrientation = true;
|
||||||
}
|
}
|
||||||
if (exifDirectory.containsTag(ExifDirectory.TAG_EXIF_IMAGE_WIDTH) &&
|
if (exifDirectory.containsTag(ExifDirectory.TAG_EXIF_IMAGE_WIDTH) &&
|
||||||
exifDirectory.containsTag(ExifDirectory.TAG_EXIF_IMAGE_HEIGHT)) {
|
exifDirectory.containsTag(ExifDirectory.TAG_EXIF_IMAGE_HEIGHT)) {
|
||||||
int width = exifDirectory.getInt(ExifDirectory.TAG_EXIF_IMAGE_WIDTH);
|
int width = exifDirectory.getInt(ExifDirectory.TAG_EXIF_IMAGE_WIDTH);
|
||||||
int height = exifDirectory.getInt(ExifDirectory.TAG_EXIF_IMAGE_HEIGHT);
|
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;
|
hasDim = true;
|
||||||
}
|
}
|
||||||
if (exifDirectory.containsTag(ExifDirectory.TAG_DATETIME_ORIGINAL)) {
|
if (exifDirectory.containsTag(ExifDirectory.TAG_DATETIME_ORIGINAL)) {
|
||||||
Date captureDate = getExifDate(exifDirectory, ExifDirectory.TAG_DATETIME_ORIGINAL);
|
Date captureDate = getExifDate(exifDirectory, ExifDirectory.TAG_DATETIME_ORIGINAL);
|
||||||
if (captureDate != null) {
|
if (captureDate != null) {
|
||||||
props.setProperty(base + "captureDate", sdf.format(captureDate));
|
props.put("captureDate", sdf.format(captureDate));
|
||||||
hasDate = true;
|
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);
|
||||||
props.setProperty(base + "comment", comment);
|
props.put("comment", comment);
|
||||||
}
|
}
|
||||||
Directory jpegDirectory = metadata.getDirectory(JpegDirectory.class);
|
Directory jpegDirectory = metadata.getDirectory(JpegDirectory.class);
|
||||||
if (jpegDirectory.containsTag(JpegDirectory.TAG_JPEG_IMAGE_WIDTH) &&
|
if (jpegDirectory.containsTag(JpegDirectory.TAG_JPEG_IMAGE_WIDTH) &&
|
||||||
jpegDirectory.containsTag(JpegDirectory.TAG_JPEG_IMAGE_HEIGHT)) {
|
jpegDirectory.containsTag(JpegDirectory.TAG_JPEG_IMAGE_HEIGHT)) {
|
||||||
int width = jpegDirectory.getInt(JpegDirectory.TAG_JPEG_IMAGE_WIDTH);
|
int width = jpegDirectory.getInt(JpegDirectory.TAG_JPEG_IMAGE_WIDTH);
|
||||||
int height = jpegDirectory.getInt(JpegDirectory.TAG_JPEG_IMAGE_HEIGHT);
|
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;
|
hasDim = true;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException("problem reading file " + f.getPath(), 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) {
|
if (!hasDate) {
|
||||||
props.setProperty(base + "captureDate", sdf.format(new Date(f.lastModified())));
|
props.put("captureDate", sdf.format(new Date(f.lastModified())));
|
||||||
}
|
}
|
||||||
if (!hasOrientation) {
|
if (!hasOrientation) {
|
||||||
props.setProperty(base + "orientation", "1");
|
props.put("orientation", "1");
|
||||||
}
|
}
|
||||||
if (!hasDim) {
|
if (!hasDim) {
|
||||||
Dimension dim = decodeImageForDimensions(f);
|
Dimension dim = decodeImageForDimensions(f);
|
||||||
if (dim != null) {
|
if (dim != null) {
|
||||||
props.setProperty(base + "dimensions", dim.toString());
|
props.put("dimensions", dim.toString());
|
||||||
hasDim = true;
|
hasDim = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
return props;
|
||||||
|
}
|
||||||
|
|
||||||
private Date getExifDate(Directory exifDirectory, int tagName) throws MetadataException {
|
private Date getExifDate(Directory exifDirectory, int tagName) throws MetadataException {
|
||||||
|
|
||||||
String dateStr = (String)exifDirectory.getObject(tagName);
|
String dateStr = (String)exifDirectory.getObject(tagName);
|
||||||
if (" : : : : ".equals(dateStr)) {
|
if (" : : : : ".equals(dateStr)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return exifDirectory.getDate(tagName);
|
return exifDirectory.getDate(tagName);
|
||||||
}
|
}
|
||||||
|
|
||||||
Dimension decodeImageForDimensions(File file) throws IOException {
|
Dimension decodeImageForDimensions(File file) throws IOException {
|
||||||
|
|
||||||
String suffix = null;
|
String suffix = null;
|
||||||
String name = file.getName();
|
String name = file.getName();
|
||||||
|
|
@ -278,10 +286,10 @@ public class DirectoryEntry extends Entry {
|
||||||
return new Dimension(img.getWidth(), img.getHeight());
|
return new Dimension(img.getWidth(), img.getHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sort() {
|
private void sort() {
|
||||||
|
|
||||||
Collections.sort(children, sort);
|
Collections.sort(children, sort);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fillLinkedList() {
|
void fillLinkedList() {
|
||||||
|
|
||||||
|
|
@ -305,19 +313,27 @@ public class DirectoryEntry extends Entry {
|
||||||
String caption = props.getProperty("caption");
|
String caption = props.getProperty("caption");
|
||||||
setCaption(caption);
|
setCaption(caption);
|
||||||
sort = ComparatorFactory.getSort(props.getProperty("sort"));
|
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();
|
|
||||||
|
Date oldest = new Date(file.lastModified());
|
||||||
|
|
||||||
|
Iterator<Object> i = props.keySet().iterator();
|
||||||
while (i.hasNext()) {
|
while (i.hasNext()) {
|
||||||
String key = (String)i.next();
|
String key = (String)i.next();
|
||||||
if (key.startsWith("file.") && key.endsWith(".dimensions")) {
|
if (key.startsWith("file.") && key.endsWith(".dimensions")) {
|
||||||
String name = key.substring("file.".length(), key.length() - ".dimensions".length());
|
String name = key.substring("file.".length(), key.length() - ".dimensions".length());
|
||||||
if (!entryMap.containsKey(name)) {
|
if (!entryMap.containsKey(name)) {
|
||||||
File f = new File(file, name);
|
File f = new File(file, name);
|
||||||
FileEntry entry = new FileEntry(this, f);
|
FileEntry entry = new FileEntry(this, f);
|
||||||
Thumbnail thumbnail = new Thumbnail(f);
|
Thumbnail thumbnail = new Thumbnail(f);
|
||||||
entry.setCaption(props.getProperty("file." + name + ".caption"));
|
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.setSize(new Dimension(props.getProperty("file." + name + ".dimensions")));
|
||||||
thumbnail.setOrientation(Integer.parseInt(props.getProperty("file." + name + ".orientation")));
|
thumbnail.setOrientation(Integer.parseInt(props.getProperty("file." + name + ".orientation")));
|
||||||
thumbnail.setEtag(props.getProperty("file." + name + ".etag"));
|
thumbnail.setEtag(props.getProperty("file." + name + ".etag"));
|
||||||
|
|
@ -331,16 +347,29 @@ public class DirectoryEntry extends Entry {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (key.startsWith("dir.") && !key.endsWith(".hidden")) {
|
} else if (key.startsWith("dir.") && !key.endsWith(".hidden")) {
|
||||||
String name = key.substring("dir.".length());
|
String name = key.substring("dir.".length());
|
||||||
boolean hidden = Boolean.parseBoolean(props.getProperty("dir." + name + ".hidden"));
|
boolean hidden = Boolean.parseBoolean(props.getProperty("dir." + name + ".hidden"));
|
||||||
if (!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()) {
|
if (thumbnail == null && !children.isEmpty()) {
|
||||||
setThumbnail(children.get(0).getThumbnail());
|
setThumbnail(children.get(0).getThumbnail());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Date getEarliest() {
|
||||||
|
loadChildren();
|
||||||
|
return earliest;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -100,4 +100,8 @@ public abstract class Entry {
|
||||||
public File getPath() {
|
public File getPath() {
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Date getEarliest() {
|
||||||
|
return getDate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ package org.forkalsrud.album.web;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
import javax.servlet.RequestDispatcher;
|
import javax.servlet.RequestDispatcher;
|
||||||
|
|
@ -230,7 +232,6 @@ public class AlbumServlet
|
||||||
public class Mapper {
|
public class Mapper {
|
||||||
|
|
||||||
public String map(File file) {
|
public String map(File file) {
|
||||||
|
|
||||||
StringBuilder buf = new StringBuilder();
|
StringBuilder buf = new StringBuilder();
|
||||||
return appendFile(buf, file).toString();
|
return appendFile(buf, file).toString();
|
||||||
}
|
}
|
||||||
|
|
@ -245,7 +246,15 @@ public class AlbumServlet
|
||||||
return appendFile(buf, file.getParentFile()).append('/').append(file.getName());
|
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
|
// eof
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue