Merge branch 'master' of ssh://odb/home/gitroot/album
Conflicts: pom.xml
This commit is contained in:
commit
8642e8c35a
6 changed files with 188 additions and 33 deletions
6
.gitignore
vendored
6
.gitignore
vendored
|
|
@ -1,3 +1,5 @@
|
|||
target
|
||||
/target
|
||||
cache.properties
|
||||
build
|
||||
/build
|
||||
/db
|
||||
|
||||
|
|
|
|||
34
pom.xml
34
pom.xml
|
|
@ -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>
|
||||
|
|
|
|||
117
src/org/forkalsrud/album/db/ThumbnailDatabase.java
Normal file
117
src/org/forkalsrud/album/db/ThumbnailDatabase.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue