Merge branch 'master' of ssh://odb/home/gitroot/album

Conflicts:
	pom.xml
This commit is contained in:
Erik Forkalsrud 2010-02-05 23:54:45 -08:00
commit 8642e8c35a
6 changed files with 188 additions and 33 deletions

6
.gitignore vendored
View file

@ -1,3 +1,5 @@
target
/target
cache.properties
build
/build
/db

34
pom.xml
View file

@ -98,7 +98,7 @@
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.drew</groupId>
<groupId>com.drewnoakes</groupId>
<artifactId>metadata-extractor</artifactId>
<version>2.3.1</version>
</dependency>
@ -108,11 +108,6 @@
<version>2.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>1.5.0</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
@ -123,15 +118,34 @@
<artifactId>junit</artifactId>
<version>4.7</version>
</dependency>
<dependency>
<groupId>com.sleepycat</groupId>
<artifactId>je</artifactId>
<version>4.0.92</version>
</dependency>
<dependency><groupId>com.caucho</groupId><artifactId>resin</artifactId><version>3.1.8</version></dependency>
</dependencies>
<repositories>
<repository>
<id>forkalsrud</id>
<id>central</id>
<name>forkalsrud.org maven proxy</name>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>false</enabled></snapshots>
<url>http://forkalsrud.org:8080/maven-proxy/repository</url>
<layout>legacy</layout>
<snapshots><enabled>true</enabled></snapshots>
<url>http://forkalsrud.org:8081/nexus/content/groups/public</url>
</repository>
<!--
<repository>
<id>oracleReleases</id>
<name>Oracle Released Java Packages</name>
<url>http://download.oracle.com/maven</url>
<layout>default</layout>
</repository>
<repository>
<id>caucho</id>
<name>caucho.com</name>
<url>http://caucho.com/m2</url>
<layout>default</layout>
</repository>
-->
</repositories>
</project>

View file

@ -0,0 +1,117 @@
/**
*
*/
package org.forkalsrud.album.db;
import java.io.File;
import java.nio.charset.Charset;
import org.forkalsrud.album.web.CachedImage;
import com.sleepycat.bind.tuple.TupleBinding;
import com.sleepycat.bind.tuple.TupleInput;
import com.sleepycat.bind.tuple.TupleOutput;
import com.sleepycat.je.Database;
import com.sleepycat.je.DatabaseConfig;
import com.sleepycat.je.DatabaseEntry;
import com.sleepycat.je.Environment;
import com.sleepycat.je.EnvironmentConfig;
import com.sleepycat.je.OperationStatus;
import com.sleepycat.je.Transaction;
/**
* @author knut
*
*/
public class ThumbnailDatabase extends TupleBinding<CachedImage> {
private static Charset UTF8 = Charset.forName("utf-8");
private Environment environment;
private Database db;
public void init(File dir) {
String dbname = "thumbnails";
EnvironmentConfig environmentConfig = new EnvironmentConfig();
environmentConfig.setAllowCreate(true);
environmentConfig.setTransactional(true);
// perform other environment configurations
environment = new Environment(dir, environmentConfig);
DatabaseConfig databaseConfig = new DatabaseConfig();
databaseConfig.setAllowCreate(true);
databaseConfig.setTransactional(true);
// perform other database configurations
this.db = environment.openDatabase(null, dbname, databaseConfig);
}
public void destroy() {
db.close();
environment.close();
}
public long size() {
return db.count();
}
public CachedImage load(String key) {
DatabaseEntry data = new DatabaseEntry();
Transaction txn = environment.beginTransaction(null, null);
OperationStatus status = db.get(txn, key(key), data, null);
txn.commitNoSync();
if (OperationStatus.SUCCESS.equals(status)) {
return entryToObject(data);
} else {
return null;
}
}
public void store(String key, CachedImage img) {
DatabaseEntry data = new DatabaseEntry();
objectToEntry(img, data);
DatabaseEntry binKey = key(key);
Transaction txn = environment.beginTransaction(null, null);
db.delete(txn, binKey);
db.put(txn, binKey, data);
txn.commitSync();
}
private DatabaseEntry key(String key) {
DatabaseEntry returnValue = new DatabaseEntry();
returnValue.setData(key.getBytes(UTF8));
return returnValue;
}
@Override
public CachedImage entryToObject(TupleInput in) {
CachedImage img = new CachedImage();
int version = in.readInt();
if (version != 1) {
throw new RuntimeException("I only understand version 1");
}
img.lastModified = in.readLong();
img.mimeType = in.readString();
int lobLen = in.readInt();
img.bits = new byte[lobLen];
in.read(img.bits, 0, lobLen);
return img;
}
@Override
public void objectToEntry(CachedImage img, TupleOutput out) {
out.writeInt(1); // version 1
out.writeLong(img.lastModified);
out.writeString(img.mimeType);
out.writeInt(img.bits.length);
out.write(img.bits);
}
}

View file

@ -4,6 +4,7 @@ import java.io.File;
import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.Properties;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
@ -11,12 +12,8 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.PropertyConfigurator;
import org.forkalsrud.album.db.ThumbnailDatabase;
import org.forkalsrud.album.exif.DirectoryEntry;
import org.forkalsrud.album.exif.Entry;
import org.forkalsrud.album.exif.FileEntry;
@ -27,38 +24,54 @@ public class AlbumServlet
{
File base;
String basePrefix;
Cache imageCache;
CacheManager cacheManager;
// Cache imageCache;
// CacheManager cacheManager;
PictureScaler pictureScaler;
long lastCacheFlushTime;
ThumbnailDatabase db = new ThumbnailDatabase();
@Override
public void init()
throws ServletException
{
log4jInit("/log4j.properties");
System.out.println("in init of Album");
base = new File(getServletConfig().getInitParameter("base")).getAbsoluteFile();
basePrefix = "/" + base.getName();
PropertyConfigurator.configure("log4j.properties");
LogFactory.getFactory().setAttribute("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.Log4JLogger");
cacheManager = CacheManager.create();
imageCache = cacheManager.getCache("imageCache");
String dbDirName = getServletConfig().getInitParameter("dbdir");
File dbDir = dbDirName != null ? new File(dbDirName) : new File(System.getProperty("java.io.tmpdir"), "album");
dbDir.mkdir();
db.init(dbDir);
// cacheManager = CacheManager.create();
// imageCache = cacheManager.getCache("imageCache");
pictureScaler = new PictureScaler();
lastCacheFlushTime = System.currentTimeMillis();
}
private void log4jInit(String resource) {
try {
Properties props = new Properties();
props.load(getClass().getResourceAsStream(resource));
PropertyConfigurator.configure(props);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public void destroy() {
imageCache.flush();
cacheManager.shutdown();
System.out.println("Shutting down Album");
db.destroy();
// imageCache.flush();
// cacheManager.shutdown();
}
@Override
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException
{
if (req.getParameter("cacheFlush") != null) imageCache.flush();
// if (req.getParameter("cacheFlush") != null) imageCache.flush();
req.setAttribute("assets", req.getContextPath() + "/assets");
req.setAttribute("req", req);
@ -166,28 +179,32 @@ public class AlbumServlet
String key = file.getPath() + ":" + size;
CachedImage cimg = null;
Element element = imageCache.get(key);
if (element != null) {
cimg = (CachedImage) element.getObjectValue();
CachedImage cimg = db.load(key);
// Element element = imageCache.get(key);
// if (element != null) {
// cimg = (CachedImage) element.getObjectValue();
if (cimg != null) {
if (cimg.lastModified == file.lastModified()) {
System.out.println("cache hit on " + key);
} else {
System.out.println(" " + key + " has changed so cache entry wil be refreshed");
imageCache.remove(key);
// imageCache.remove(key);
cimg = null;
}
}
if (cimg == null) {
// try {
cimg = pictureScaler.scalePicture(file, thumbnail, size);
imageCache.put(new Element(key, cimg));
db.store(key, cimg);
// imageCache.put(new Element(key, cimg));
/*
long millisSinceLastFlush = System.currentTimeMillis() - lastCacheFlushTime;
if (millisSinceLastFlush > 10 * 60 * 1000L) {
imageCache.flush();
lastCacheFlushTime = System.currentTimeMillis();
}
System.out.println(" " + key + " added to the cache with size " + cimg.bits.length + " -- now " + imageCache.getSize() + " entries");
*/
System.out.println(" " + key + " added to the cache with size " + cimg.bits.length + " -- now " + db.size() + " entries");
// } catch (TimeoutException e) {
// res.setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
// return;

View file

@ -171,6 +171,7 @@ public class PictureScaler {
reader.setInput(iis, true);
ImageReadParam param = reader.getDefaultReadParam();
BufferedImage img = reader.read(0, param);
iis.close();
// The orientation is about flipping and rotating. Here is what an 'F' looks like
// on pictures with each orientation.

View file

@ -19,6 +19,10 @@
<param-name>base</param-name>
<param-value>photos</param-value>
</init-param>
<init-param>
<param-name>dbdir</param-name>
<param-value>db</param-value>
</init-param>
</servlet>
<servlet>