Subversion Repositories general

Compare Revisions

Ignore whitespace Rev 935 → Rev 936

/sun/PhotoAlbum/trunk/src/ak/photoalbum/util/FileUtils.java
0,0 → 1,79
package ak.photoalbum.util;
 
import java.util.Map;
import java.util.HashMap;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
 
public class FileUtils
{
protected static final int COPY_BUFFER_SIZE = 4096;
protected static final Map MIME_MAP = new HashMap();
 
static {
MIME_MAP.put("jpg", "image/jpeg");
MIME_MAP.put("jpeg", "image/jpeg");
MIME_MAP.put("png", "image/png");
}
 
public static String getMime(String ext)
{
if(ext == null)
return null;
else
return (String)MIME_MAP.get(ext.toLowerCase());
}
 
public static void copyStreams(InputStream in, OutputStream out)
throws IOException
{
byte[] buf = new byte[COPY_BUFFER_SIZE];
int len;
 
while((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
}
 
public static String extractFileName(String fullName)
{
if(fullName == null) return null;
 
int pointPos = fullName.lastIndexOf('.');
 
if(pointPos <= 0)
return fullName;
else
return fullName.substring(0, pointPos);
}
 
public static String extractFileExt(String fullName)
{
if(fullName == null) return null;
 
int pointPos = fullName.lastIndexOf('.');
 
if(pointPos <= 0)
return "";
else
return fullName.substring(pointPos + 1);
}
 
public static String replaceFileSeparator(String path, String replaceWith)
{
String sep = File.separator;
StringBuffer buf = new StringBuffer();
int pos = -1;
int oldPos = -1;
 
while((pos = path.indexOf(sep, pos + 1)) >= 0) {
buf.append(path.substring(oldPos + 1, pos)).append(replaceWith);
oldPos = pos;
}
buf.append(path.substring(oldPos + 1));
 
return buf.toString();
}
}
/sun/PhotoAlbum/trunk/src/ak/photoalbum/util/FileNameComparator.java
0,0 → 1,31
package ak.photoalbum.util;
 
import java.util.Comparator;
import java.io.File;
 
public class FileNameComparator
implements Comparator
{
private boolean dirFirst;
 
public FileNameComparator(boolean dirFirst)
{
this.dirFirst = dirFirst;
}
 
public int compare(Object o1, Object o2)
throws ClassCastException
{
return compare((File)o1, (File)o2);
}
 
public int compare(File f1, File f2)
{
boolean d1 = f1.isDirectory();
boolean d2 = f2.isDirectory();
 
if(d1 && !d2) return (dirFirst ? -1 : 1);
else if(!d1 && d2) return (dirFirst ? 1 : -1);
else return f1.getName().compareToIgnoreCase(f2.getName());
}
}
/sun/PhotoAlbum/trunk/src/ak/photoalbum/util/ImagesFilter.java
0,0 → 1,37
package ak.photoalbum.util;
 
import java.io.File;
import java.io.FileFilter;
import java.util.Set;
import java.util.HashSet;
import java.util.StringTokenizer;
 
public class ImagesFilter
implements FileFilter
{
Set extentions = new HashSet();
 
public ImagesFilter(String imagesMask)
{
StringTokenizer tokenizer = new StringTokenizer(imagesMask, ";");
 
while(tokenizer.hasMoreTokens()) {
String token = tokenizer.nextToken();
 
if(token.startsWith("*.")) token = token.substring(2);
 
extentions.add(token.toLowerCase());
}
}
 
public boolean accept(File pathname)
{
if(pathname.isDirectory()) {
return !pathname.getName().startsWith("."); // skip hidden dirs
}
else{
return extentions.contains(FileUtils.extractFileExt(
pathname.getName().toLowerCase()));
}
}
}
/sun/PhotoAlbum/trunk/src/ak/photoalbum/webapp/IndexAction.java
0,0 → 1,45
package ak.photoalbum.webapp;
 
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.log4j.Logger;
import ak.photoalbum.util.FileUtils;
 
public final class IndexAction
extends BaseAction
{
private static final Logger logger = Logger.getLogger(IndexAction.class);
 
public ActionForward executeAction(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception
{
PathForm theForm = (PathForm)form;
String dir = theForm.getPath();
IndexEntry entry = new IndexEntry();
IndexEntry top = new IndexEntry();
IndexEntry prev = new IndexEntry();
IndexEntry current = new IndexEntry();
IndexEntry next = new IndexEntry();
List index;
 
if(dir == null) dir = ""; // the images root
 
logger.info("get index for " + dir);
Logic.getLogic().getEntry(dir, entry, top, prev, current, next);
index = Logic.getLogic().listDirectory(dir);
 
request.setAttribute("dir", FileUtils.replaceFileSeparator(dir, " - "));
request.setAttribute("index", index);
request.setAttribute("top", top);
request.setAttribute("prevEntry", prev);
request.setAttribute("current", current);
request.setAttribute("nextEntry", next);
 
return mapping.findForward("success");
}
}
/sun/PhotoAlbum/trunk/src/ak/photoalbum/webapp/BaseAction.java
0,0 → 1,51
package ak.photoalbum.webapp;
 
import java.util.List;
import java.io.FileNotFoundException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.log4j.Logger;
import ak.photoalbum.util.FileUtils;
 
public abstract class BaseAction
extends Action
{
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception
{
Logger logger = Logger.getLogger(getClass());
 
try {
return executeAction(mapping, form, request, response);
}
catch(LogicSecurityException ex) {
logger.warn("forbidden: " + ex.getMessage());
logger.debug("forbidden", ex);
response.sendError(HttpServletResponse.SC_FORBIDDEN);
 
return null;
}
catch(FileNotFoundException ex) {
logger.warn("not found: " + ex.getMessage());
logger.debug("not found", ex);
response.sendError(HttpServletResponse.SC_NOT_FOUND);
 
return null;
}
catch(Exception ex) {
logger.error("exception", ex);
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
 
return null;
}
}
 
public abstract ActionForward executeAction(ActionMapping mapping,
ActionForm form, HttpServletRequest request, HttpServletResponse response)
throws Exception;
}
/sun/PhotoAlbum/trunk/src/ak/photoalbum/webapp/InitServlet.java
0,0 → 1,50
package ak.photoalbum.webapp;
 
import javax.servlet.ServletException;
import javax.servlet.ServletConfig;
import javax.servlet.http.HttpServlet;
 
public class InitServlet
extends HttpServlet
{
public void init()
throws ServletException
{
ServletConfig config = getServletConfig();
 
String imagesRoot;
String imagesMask;
String cacheDir;
String thumbnailFormat;
Integer smallWidth = null;
Integer smallHeight = null;
Integer mediumWidth = null;
Integer mediumHeight = null;
Integer columns = null;
String dirTemplate;
String dirThumbnailPositions;
 
imagesRoot = config.getInitParameter("images root");
imagesMask = config.getInitParameter("images mask");
cacheDir = config.getInitParameter("cache dir");
thumbnailFormat = config.getInitParameter("thumbnail format");
 
if(config.getInitParameter("small width") != null)
smallWidth = new Integer(config.getInitParameter("small width"));
if(config.getInitParameter("small height") != null)
smallHeight = new Integer(config.getInitParameter("small height"));
if(config.getInitParameter("medium width") != null)
mediumWidth = new Integer(config.getInitParameter("medium width"));
if(config.getInitParameter("medium heught") != null)
mediumHeight = new Integer(config.getInitParameter("medium heught"));
if(config.getInitParameter("columns") != null)
columns = new Integer(config.getInitParameter("columns"));
 
dirTemplate = config.getInitParameter("dir template");
dirThumbnailPositions = config.getInitParameter("dir thumbnails positions");
 
Logic.getLogic().init(imagesRoot, imagesMask, cacheDir, thumbnailFormat,
smallWidth, smallHeight, mediumWidth, mediumHeight, columns,
dirTemplate, dirThumbnailPositions);
}
}
/sun/PhotoAlbum/trunk/src/ak/photoalbum/webapp/IndexEntry.java
0,0 → 1,94
package ak.photoalbum.webapp;
 
import java.io.File;
 
public class IndexEntry
{
private File file;
private String path;
private String title;
private boolean isDir;
private int width;
private int height;
 
public IndexEntry()
{
}
 
public IndexEntry(File file, String path, String title, boolean isDir,
int width, int height)
{
this.file = file;
this.path = path;
this.title = title;
this.isDir = isDir;
this.width = width;
this.height = height;
}
 
public File getFile()
{
return file;
}
 
public void setFile(File file)
{
this.file = file;
}
 
public String getPath()
{
return path;
}
 
public void setPath(String path)
{
this.path = path;
}
 
public String getTitle()
{
return title;
}
 
public void setTitle(String title)
{
this.title = title;
}
 
public boolean getIsDir()
{
return isDir;
}
 
public void setIsDir(boolean isDir)
{
this.isDir = isDir;
}
 
public int getWidth()
{
return width;
}
 
public void setWidth(int width)
{
this.width = width;
}
 
public int getHeight()
{
return height;
}
 
public void setHeight(int height)
{
this.height = height;
}
 
public String toString()
{
return super.toString() + ": " + file + " - " + path + " - " + title
+ " " + width + "x" + height;
}
}
/sun/PhotoAlbum/trunk/src/ak/photoalbum/webapp/PageAction.java
0,0 → 1,41
package ak.photoalbum.webapp;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.log4j.Logger;
 
public final class PageAction
extends BaseAction
{
private static final Logger logger = Logger.getLogger(IndexAction.class);
 
public ActionForward executeAction(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception
{
PathForm theForm = (PathForm)form;
String page = theForm.getPath();
IndexEntry entry = new IndexEntry();
IndexEntry index = new IndexEntry();
IndexEntry prev = new IndexEntry();
IndexEntry current = new IndexEntry();
IndexEntry next = new IndexEntry();
 
if(page == null) page = ""; // the images root
 
logger.info("get page " + page);
Logic.getLogic().getEntry(page, entry, index, prev, current, next);
 
request.setAttribute("page", page);
request.setAttribute("entry", entry);
request.setAttribute("index", index);
request.setAttribute("prevEntry", prev);
request.setAttribute("current", current);
request.setAttribute("nextEntry", next);
 
return mapping.findForward("success");
}
}
/sun/PhotoAlbum/trunk/src/ak/photoalbum/webapp/LogicException.java
0,0 → 1,10
package ak.photoalbum.webapp;
 
public class LogicException
extends Exception
{
public LogicException(String message)
{
super(message);
}
}
/sun/PhotoAlbum/trunk/src/ak/photoalbum/webapp/Logic.java
0,0 → 1,342
package ak.photoalbum.webapp;
 
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.StringTokenizer;
import java.io.File;
import java.io.IOException;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.io.FileNotFoundException;
import java.net.URLEncoder;
import org.apache.log4j.Logger;
import ak.photoalbum.images.Thumbnailer;
import ak.photoalbum.images.ThumbnailPosition;
import ak.photoalbum.util.FileUtils;
import ak.photoalbum.util.FileNameComparator;
import ak.photoalbum.util.ImagesFilter;
 
public class Logic
{
protected static final int DEFAULT_COLUMNS = 4;
protected static final String URL_ENCODING = "UTF-8";
 
protected Logger logger;
protected Thumbnailer thumbnailer;
protected File imagesRoot;
protected int columns = DEFAULT_COLUMNS;
protected ImagesFilter imagesFilter;
protected Comparator fileNameComparator = new FileNameComparator(true);
 
protected Logic()
{
this.logger = Logger.getLogger(this.getClass());
}
 
public void init(String imagesRoot, String imagesMask,
String cacheDir, String thumbnailFormat,
Integer smallWidth, Integer smallHeight,
Integer mediumWidth, Integer mediumHeight, Integer columns,
String dirTemplate, String dirThumbnailPositions)
{
this.imagesRoot = new File(imagesRoot);
this.imagesFilter = new ImagesFilter(imagesMask);
if(columns != null) this.columns = columns.intValue();
 
this.thumbnailer = new Thumbnailer();
this.thumbnailer.setImagesRoot(this.imagesRoot);
this.thumbnailer.setCacheDir(new File(cacheDir));
 
if(thumbnailFormat != null)
this.thumbnailer.setFormat(thumbnailFormat);
if(smallWidth != null)
this.thumbnailer.setSmallWidth(smallWidth.intValue());
if(smallHeight != null)
this.thumbnailer.setSmallHeight(smallHeight.intValue());
if(mediumWidth != null)
this.thumbnailer.setMediumWidth(mediumWidth.intValue());
if(mediumHeight != null)
this.thumbnailer.setMediumHeight(mediumHeight.intValue());
 
thumbnailer.setResizer(new ak.photoalbum.images.jiu.JiuResizer());
thumbnailer.setImagesFilter(this.imagesFilter);
thumbnailer.setDirTemplate(new File(dirTemplate));
thumbnailer.setDirThumbnailPositions(
parseThumbnailPositions(dirThumbnailPositions));
 
try {
thumbnailer.startup();
}
catch(Exception ex) {
logger.error("init thumbnailer", ex);
}
 
logger.info("started");
}
 
public void buildCache()
throws IOException
{
thumbnailer.buildCache();
}
 
public void getEntry(String path, IndexEntry page,
IndexEntry index, IndexEntry prev, IndexEntry current, IndexEntry next)
throws IOException, LogicException
{
File file = new File(imagesRoot, path);
 
securePath(imagesRoot, file);
 
if(!file.exists())
throw new FileNotFoundException(
"[" + file.getCanonicalPath() + "] not found");
 
File dir = file.getParentFile();
File[] children = dir.listFiles(imagesFilter);
int pos;
 
Arrays.sort(children, fileNameComparator);
pos = Arrays.binarySearch(children, file, fileNameComparator);
 
if(pos < 0)
throw new FileNotFoundException("[" + file.getCanonicalPath()
+ "] not found in [" + dir.getCanonicalPath() + "]");
 
setEntryInfo(page, file, false);
setEntryInfo(current, file, true);
setEntryInfo(index, dir, true);
if(pos > 0) setEntryInfo(prev, children[pos-1], true);
if(pos < children.length-1) setEntryInfo(next, children[pos+1], true);
}
 
protected void setEntryInfo(IndexEntry entry, File file, boolean small)
throws IOException
{
String title = file.getName();
int[] size;
String path = getPath(file);
 
if(file.isDirectory()) {
size = thumbnailer.getDirSize(file);
}
else {
title = FileUtils.extractFileName(title);
 
if(small)
size = thumbnailer.getSmallSize(file);
else
size = thumbnailer.getMediumSize(file);
}
 
entry.setFile(file);
entry.setPath(path == null ? null : URLEncoder.encode(path, URL_ENCODING));
entry.setTitle(title);
entry.setIsDir(file.isDirectory());
entry.setWidth(size[0]);
entry.setHeight(size[1]);
}
 
public String getThumbnailMime()
{
return thumbnailer.getMime();
}
 
public String getOriginMime(String path)
throws IOException, LogicException
{
File file = new File(imagesRoot, path);
 
if(!file.exists()) return null;
securePath(imagesRoot, file);
 
return FileUtils.getMime(FileUtils.extractFileExt(path));
}
 
public void writeDir(String path, OutputStream out)
throws IOException, LogicException
{
File file = new File(imagesRoot, path);
 
securePath(imagesRoot, file);
thumbnailer.writeDir(file, out);
}
 
public void writeSmall(String path, OutputStream out)
throws IOException, LogicException
{
File file = new File(imagesRoot, path);
 
securePath(imagesRoot, file);
thumbnailer.writeSmall(file, out);
}
 
public void writeMedium(String path, OutputStream out)
throws IOException, LogicException
{
File file = new File(imagesRoot, path);
 
securePath(imagesRoot, file);
thumbnailer.writeMedium(file, out);
}
 
public void writeOrigin(String path, OutputStream out)
throws IOException, LogicException
{
FileInputStream in = null;
File file = new File(imagesRoot, path);
 
securePath(imagesRoot, file);
 
try {
in = new FileInputStream(file);
FileUtils.copyStreams(in, out);
}
finally {
if(in != null) in.close();
}
}
 
public List listDirectory(String dirName)
throws UnsupportedEncodingException, IOException, LogicException
{
File dir = new File(imagesRoot, dirName);
 
securePath(imagesRoot, dir);
if(!dir.exists()) return null;
 
File[] children = dir.listFiles(imagesFilter);
List rows = new ArrayList();
int pos = 0;
 
Arrays.sort(children, fileNameComparator);
 
while(pos < children.length) {
List row = new ArrayList();
int rowPos = 0;
 
rows.add(row);
 
while(rowPos < columns && pos < children.length) {
String path = getPath(children[pos]);
String title = children[pos].getName();
int[] size;
 
if(children[pos].isDirectory()) {
size = thumbnailer.getDirSize(children[pos]);
}
else {
size = thumbnailer.getSmallSize(children[pos]);
title = FileUtils.extractFileName(title);
}
 
row.add(new IndexEntry(children[pos],
URLEncoder.encode(path, URL_ENCODING),
title, children[pos].isDirectory(), size[0], size[1]));
rowPos++;
pos++;
}
 
while(rowPos < columns) {
row.add(null);
rowPos++;
}
}
 
return rows;
}
 
protected String getPath(File file)
throws IOException
{
String path = file.getCanonicalPath();
String rootPath = imagesRoot.getCanonicalPath();
 
if(path.equals(rootPath)) return "";
if(!rootPath.endsWith(File.separator)) rootPath += File.separator;
 
if(!path.startsWith(rootPath))
return null;
 
return path.substring(rootPath.length());
}
 
protected ThumbnailPosition[] parseThumbnailPositions(String str)
{
List list = new ArrayList();
StringTokenizer tokenizer = new StringTokenizer(str, ";");
 
while(tokenizer.hasMoreTokens()) {
StringTokenizer tokenParser
= new StringTokenizer(tokenizer.nextToken(), ",");
int x = Integer.parseInt(tokenParser.nextToken().trim());
int y = Integer.parseInt(tokenParser.nextToken().trim());
int width = Integer.parseInt(tokenParser.nextToken().trim());
int height = Integer.parseInt(tokenParser.nextToken().trim());
String horAlignStr = tokenParser.nextToken().trim().toLowerCase();
String vertAlignStr = tokenParser.nextToken().trim().toLowerCase();
int horAlign;
int vertAlign;
 
if("l".equals(horAlignStr))
horAlign = ThumbnailPosition.ALIGN_HOR_LEFT;
else if("r".equals(horAlignStr))
horAlign = ThumbnailPosition.ALIGN_HOR_RIGHT;
else if("c".equals(horAlignStr))
horAlign = ThumbnailPosition.ALIGN_HOR_CENTER;
else
throw new RuntimeException(
"Cannot parse " + horAlignStr + " as horizontal alignment");
 
if("t".equals(vertAlignStr))
vertAlign = ThumbnailPosition.ALIGN_VERT_TOP;
else if("b".equals(vertAlignStr))
vertAlign = ThumbnailPosition.ALIGN_VERT_BOTTOM;
else if("c".equals(vertAlignStr))
vertAlign = ThumbnailPosition.ALIGN_VERT_CENTER;
else
throw new RuntimeException(
"Cannot parse " + vertAlignStr + " as vertical alignment");
 
list.add(new ThumbnailPosition(x, y, width, height, horAlign, vertAlign));
}
 
ThumbnailPosition[] res = new ThumbnailPosition[list.size()];
 
for(int i = 0; i < res.length; i++)
res[i] = (ThumbnailPosition)list.get(i);
 
return res;
}
 
protected static final Logic instance = new Logic();
 
public static Logic getLogic()
{
return instance;
}
 
/**
* checks if given file is really under the parent directory
*/
protected void securePath(File parentDir, File file)
throws IOException, LogicException
{
if(parentDir == null || file == null) return;
 
File partFile = file.getCanonicalFile();
 
parentDir = parentDir.getCanonicalFile();
while(partFile != null) {
if(partFile.equals(parentDir)) return;
partFile = partFile.getParentFile();
}
 
throw new LogicSecurityException(
"[" + file.getCanonicalPath() + "] is outside of directory ["
+ parentDir.getCanonicalPath() + "]");
}
}
/sun/PhotoAlbum/trunk/src/ak/photoalbum/webapp/ImageAction.java
0,0 → 1,45
package ak.photoalbum.webapp;
 
import java.io.FileNotFoundException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.log4j.Logger;
 
public final class ImageAction
extends BaseAction
{
private static final Logger logger = Logger.getLogger(ImageAction.class);
 
public ActionForward executeAction(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception
{
PathForm theForm = (PathForm)form;
String path = theForm.getPath();
Logic logic = Logic.getLogic();
 
logger.info("get image " + mapping.getParameter() + " for " + path);
 
if("dir".equals(mapping.getParameter())) {
response.setContentType(logic.getThumbnailMime());
logic.writeDir(path, response.getOutputStream());
}
else if("small".equals(mapping.getParameter())) {
response.setContentType(logic.getThumbnailMime());
logic.writeSmall(path, response.getOutputStream());
}
else if("medium".equals(mapping.getParameter())) {
response.setContentType(logic.getThumbnailMime());
logic.writeMedium(path, response.getOutputStream());
}
else if("origin".equals(mapping.getParameter())) {
response.setContentType(logic.getOriginMime(path));
logic.writeOrigin(path, response.getOutputStream());
}
 
return null;
}
}
/sun/PhotoAlbum/trunk/src/ak/photoalbum/webapp/PathForm.java
0,0 → 1,31
package ak.photoalbum.webapp;
 
import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
 
public class PathForm
extends ActionForm
{
protected String path;
 
public String getPath()
{
return path;
}
 
public void setPath(String path)
{
this.path = path;
}
 
public ActionErrors validate(ActionMapping mapping,
HttpServletRequest request)
{
ActionErrors errors = new ActionErrors();
 
return errors;
}
}
/sun/PhotoAlbum/trunk/src/ak/photoalbum/webapp/BuildCacheAction.java
0,0 → 1,25
package ak.photoalbum.webapp;
 
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.log4j.Logger;
 
public final class BuildCacheAction
extends Action
{
private static final Logger logger = Logger.getLogger(IndexAction.class);
 
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception
{
Logic.getLogic().buildCache();
 
return mapping.findForward("success");
}
}
/sun/PhotoAlbum/trunk/src/ak/photoalbum/webapp/LogicSecurityException.java
0,0 → 1,10
package ak.photoalbum.webapp;
 
public class LogicSecurityException
extends LogicException
{
public LogicSecurityException(String message)
{
super(message);
}
}
/sun/PhotoAlbum/trunk/src/ak/photoalbum/images/ImageResizer.java
0,0 → 1,9
package ak.photoalbum.images;
 
import java.awt.Image;
import java.awt.image.BufferedImage;
 
public interface ImageResizer
{
public BufferedImage resize(Image origin, int newWidth, int newHeight);
}
/sun/PhotoAlbum/trunk/src/ak/photoalbum/images/CachedFile.java
0,0 → 1,99
package ak.photoalbum.images;
 
import java.io.File;
 
class CachedFile
{
private File file;
private File originFile;
private long timestamp;
private long originTimestamp;
private int width;
private int height;
 
public CachedFile()
{
}
 
public CachedFile(File file, File originFile, long timestamp,
long originTimestamp, int width, int height)
{
this.file = file;
this.originFile = originFile;
this.timestamp = timestamp;
this.originTimestamp = originTimestamp;
this.width = width;
this.height = height;
}
 
public File getFile()
{
return file;
}
 
public void setFile(File file)
{
this.file = file;
}
 
public File getOriginFile()
{
return originFile;
}
 
public void setOriginFile(File file)
{
this.originFile = file;
}
 
public long getTimestamp()
{
return timestamp;
}
 
public void setTimestamp(long timestamp)
{
this.timestamp = timestamp;
}
 
public long getOriginTimestamp()
{
return originTimestamp;
}
 
public void setOriginTimestamp(long timestamp)
{
this.originTimestamp = timestamp;
}
 
public int getWidth()
{
return width;
}
 
public void setWidth(int width)
{
this.width = width;
}
 
public int getHeight()
{
return height;
}
 
public void setHeight(int height)
{
this.height = height;
}
 
public String toString()
{
return super.toString() + ":"
+ " file=" + file
+ " originFile=" + originFile
+ " timestamp=" + timestamp
+ " originTimestamp=" + originTimestamp
+ " width=" + width
+ " height=" + height;
}
}
/sun/PhotoAlbum/trunk/src/ak/photoalbum/images/jiu/JiuResizer.java
0,0 → 1,205
package ak.photoalbum.images.jiu;
 
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.PixelGrabber;
import java.awt.image.ImageObserver;
 
import org.apache.log4j.Logger;
 
import ak.photoalbum.images.ImageResizer;
 
import net.sourceforge.jiu.data.BilevelImage;
import net.sourceforge.jiu.data.Gray8Image;
import net.sourceforge.jiu.data.MemoryRGB24Image;
import net.sourceforge.jiu.data.Palette;
import net.sourceforge.jiu.data.Paletted8Image;
import net.sourceforge.jiu.data.PixelImage;
import net.sourceforge.jiu.data.RGB24Image;
import net.sourceforge.jiu.data.RGBIndex;
import net.sourceforge.jiu.geometry.Resample;
 
public class JiuResizer
implements ImageResizer
{
protected static final int DEFAULT_ALPHA = 0xff000000;
protected static final int FILTER_TYPE = Resample.FILTER_TYPE_LANCZOS3;
/*
Possible type small, ms medium, ms quality
-----------------------------------------------------------
FILTER_TYPE_BOX 2.4 3.5 very bad
FILTER_TYPE_TRIANGLE 2.9 5.2
FILTER_TYPE_B_SPLINE 3.6 7.2
FILTER_TYPE_BELL 3.5 6.1
FILTER_TYPE_HERMITE 2.9 5.3
FILTER_TYPE_LANCZOS3 4.7 9.7 the best
FILTER_TYPE_MITCHELL 3.6 7.1
*/
 
protected Logger logger;
 
public JiuResizer()
{
this.logger = Logger.getLogger(this.getClass());
}
 
public BufferedImage resize(Image origin, int newWidth, int newHeight)
{
try {
RGB24Image image = convertImageToRGB24Image(origin);
Resample resample;
 
if(image == null) return null;
if(image.getWidth() == newWidth && image.getHeight() == newHeight)
return convertToAwtImage(image, DEFAULT_ALPHA);
 
resample = new Resample();
resample.setInputImage(image);
resample.setSize(newWidth, newHeight);
resample.setFilter(FILTER_TYPE);
resample.process();
 
return convertToAwtImage(resample.getOutputImage(), DEFAULT_ALPHA);
}
catch(Exception ex) {
ex.printStackTrace();
 
throw new RuntimeException(ex.getMessage());
}
}
 
protected static BufferedImage convertToAwtImage(PixelImage image, int alpha)
{
if (image == null)
{
return null;
}
if (image instanceof RGB24Image)
{
return convertToAwtImage((RGB24Image)image, alpha);
}
else
if (image instanceof Gray8Image)
{
return null; //convertToAwtImage((Gray8Image)image, alpha);
}
else
if (image instanceof Paletted8Image)
{
return null; //convertToAwtImage((Paletted8Image)image, alpha);
}
else
if (image instanceof BilevelImage)
{
return null; //convertToAwtImage((BilevelImage)image, alpha);
}
else
{
return null;
}
}
 
protected static BufferedImage convertToAwtImage(RGB24Image image, int alpha)
{
if (image == null)
{
return null;
}
 
int width = image.getWidth();
int height = image.getHeight();
if (width < 1 || height < 1)
{
return null;
}
 
int[] pixels = new int[width];
byte[] red = new byte[width];
byte[] green = new byte[width];
byte[] blue = new byte[width];
 
BufferedImage newImage = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
 
for (int y = 0; y < height; y++)
{
image.getByteSamples(RGBIndex.INDEX_RED, 0, y, width, 1, red, 0);
image.getByteSamples(RGBIndex.INDEX_GREEN, 0, y, width, 1, green, 0);
image.getByteSamples(RGBIndex.INDEX_BLUE, 0, y, width, 1, blue, 0);
convertFromRGB24(red, 0, green, 0, blue, 0, alpha, pixels, 0, width);
 
for(int x = 0; x < width; x++)
newImage.setRGB(x, y, pixels[x]);
}
 
return newImage;
}
 
protected static void convertFromRGB24(
byte[] srcRed, int srcRedOffset,
byte[] srcGreen, int srcGreenOffset,
byte[] srcBlue, int srcBlueOffset,
int alpha,
int[] dest, int destOffset,
int num)
{
while (num-- > 0)
{
dest[destOffset++] =
alpha |
(srcBlue[srcBlueOffset++] & 0xff) |
((srcGreen[srcGreenOffset++] & 0xff) << 8) |
((srcRed[srcRedOffset++] & 0xff) << 16);
}
}
 
/**
* Creates an {@link RGB24Image} from the argument AWT image instance.
* @param image AWT image object to be converted to a {@link RGB24Image}
* @return a {@link RGB24Image} object holding the
* image data from the argument image
*/
protected static RGB24Image convertImageToRGB24Image(Image image)
{
if (image == null)
{
return null;
}
int width = image.getWidth(null);
int height = image.getHeight(null);
if (width < 1 || height < 1)
{
return null;
}
int[] pixels = new int[width * height];
PixelGrabber pg = new PixelGrabber(
image, 0, 0, width, height, pixels, 0, width);
 
try
{
pg.grabPixels();
}
catch (InterruptedException e)
{
return null;
}
if ((pg.getStatus() & ImageObserver.ABORT) != 0)
{
//System.err.println("image fetch aborted or errored");
return null;
}
RGB24Image result = new MemoryRGB24Image(width, height);
int offset = 0;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
int pixel = pixels[offset++] & 0xffffff;
result.putSample(RGBIndex.INDEX_RED, x, y, pixel >> 16);
result.putSample(RGBIndex.INDEX_GREEN, x, y, (pixel >> 8) & 0xff);
result.putSample(RGBIndex.INDEX_BLUE, x, y, pixel & 0xff);
}
}
return result;
}
}
/sun/PhotoAlbum/trunk/src/ak/photoalbum/images/ThumbnailPosition.java
0,0 → 1,89
package ak.photoalbum.images;
 
public class ThumbnailPosition
{
public static final int ALIGN_HOR_LEFT = 1;
public static final int ALIGN_HOR_RIGHT = 2;
public static final int ALIGN_HOR_CENTER = 3;
public static final int ALIGN_VERT_TOP = 1;
public static final int ALIGN_VERT_BOTTOM = 2;
public static final int ALIGN_VERT_CENTER = 3;
 
private int x;
private int y;
private int width;
private int height;
private int horAlign;
private int vertAlign;
 
public ThumbnailPosition(int x, int y, int width, int height,
int horAlign, int vertAlign)
{
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.horAlign = horAlign;
this.vertAlign = vertAlign;
}
 
public int getX()
{
return x;
}
 
public void setX(int x)
{
this.x = x;
}
 
public int getY()
{
return y;
}
 
public void setY(int y)
{
this.y = y;
}
 
public int getWidth()
{
return width;
}
 
public void setWidth(int width)
{
this.width = width;
}
 
public int getHeight()
{
return height;
}
 
public void setHeight(int height)
{
this.height = height;
}
 
public int getHorAlign()
{
return horAlign;
}
 
public void setHorAlign(int horAlign)
{
this.horAlign = horAlign;
}
 
public int getVertAlign()
{
return vertAlign;
}
 
public void setVertAlign(int vertAlign)
{
this.vertAlign = vertAlign;
}
}
/sun/PhotoAlbum/trunk/src/ak/photoalbum/images/Thumbnailer.java
0,0 → 1,799
package ak.photoalbum.images;
 
import java.util.Map;
import java.util.HashMap;
import java.util.Comparator;
import java.util.Arrays;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import java.awt.image.PixelGrabber;
import javax.imageio.ImageIO;
import org.apache.log4j.Logger;
import marcoschmidt.image.ImageInfo;
import ak.photoalbum.util.FileUtils;
import ak.photoalbum.util.FileNameComparator;
 
public class Thumbnailer
{
protected static final String DEFAULT_FORMAT = "jpg";
protected static final String SMALL_SUFFIX = ".small";
protected static final String MEDIUM_SUFFIX = ".medium";
protected static final String DIR_SUFFIX = ".dir";
protected static final int DEFAULT_SMALL_WIDTH = 120;
protected static final int DEFAULT_SMALL_HEIGHT = 120;
protected static final int DEFAULT_MEDIUM_WIDTH = 800;
protected static final int DEFAULT_MEDIUM_HEIGHT = 800;
 
protected Logger logger;
protected ImageResizer resizer;
protected int smallWidth = DEFAULT_SMALL_WIDTH;
protected int smallHeight = DEFAULT_SMALL_HEIGHT;
protected int mediumWidth = DEFAULT_MEDIUM_WIDTH;
protected int mediumHeight = DEFAULT_MEDIUM_HEIGHT;
protected File cacheDir;
protected String format = DEFAULT_FORMAT;
protected Map smallCache = new HashMap();
protected Map mediumCache = new HashMap();
protected Map dirCache = new HashMap();
protected File imagesRoot;
protected FileFilter imagesFilter = null;
protected Comparator fileNameComparator = new FileNameComparator(true);
protected Comparator fileNameComparatorRev = new FileNameComparator(false);
 
protected File dirTemplate;
protected ThumbnailPosition[] dirThumbnailPositions;
protected int[] dirTemplateSize;
protected long dirTemplateTimestamp;
 
public Thumbnailer()
{
this.logger = Logger.getLogger(this.getClass());
}
 
public String getMime()
{
return FileUtils.getMime(format);
}
 
public int[] getDirSize(File origin)
throws IOException
{
if(dirTemplateSize == null
|| dirTemplateTimestamp != dirTemplate.lastModified())
{
dirTemplateSize = getOriginSize(dirTemplate);
dirTemplateTimestamp = dirTemplate.lastModified();
}
 
return dirTemplateSize;
}
 
public int[] getSmallSize(File origin)
throws IOException
{
CachedFile cached = getCached(smallCache, origin);
 
if(cached == null) {
int[] originSize = getOriginSize(origin);
 
return calcSizes(originSize[0], originSize[1], smallWidth, smallHeight);
}
else {
int[] originSize = new int[2];
 
originSize[0] = cached.getWidth();
originSize[1] = cached.getHeight();
 
return originSize;
}
}
 
public int[] getMediumSize(File origin)
throws IOException
{
CachedFile cached = getCached(mediumCache, origin);
 
if(cached == null) {
int[] originSize = getOriginSize(origin);
 
return calcSizes(originSize[0], originSize[1], mediumWidth, mediumHeight);
}
else {
int[] originSize = new int[2];
 
originSize[0] = cached.getWidth();
originSize[1] = cached.getHeight();
 
return originSize;
}
}
 
protected int[] getOriginSize(File origin)
throws IOException
{
if(logger.isDebugEnabled())
logger.debug("get size of " + origin.getCanonicalPath());
 
ImageInfo ii = new ImageInfo();
FileInputStream in = null;
int[] res = new int[2];
 
try {
in = new FileInputStream(origin);
ii.setInput(in);
 
if(!ii.check()) {
logger.warn("not supported format of " + origin.getCanonicalPath());
res[0] = 0;
res[1] = 0;
}
else{
res[0] = ii.getWidth();
res[1] = ii.getHeight();
}
}
finally {
if(in != null) in.close();
}
 
return res;
}
 
public void rebuildCache()
throws IOException
{
logger.info("rebuild cache");
 
deleteCache();
buildCache();
}
 
public void deleteCache()
throws IOException
{
logger.info("delete cache");
 
deleteCache(cacheDir);
}
 
public void buildCache()
throws IOException
{
logger.info("build cache");
 
buildCache(imagesRoot);
}
 
protected void deleteCache(File dir)
throws IOException
{
File[] children = dir.listFiles();
 
if(children == null) return; // the dir does not exists
 
Arrays.sort(children, fileNameComparator);
 
for(int i = 0; i < children.length; i++) {
if(children[i].isDirectory())
deleteCache(children[i]);
else
children[i].delete();
}
dir.delete();
}
 
protected void buildCache(File dir)
throws IOException
{
File[] children;
 
if(imagesFilter == null)
children = dir.listFiles();
else
children = dir.listFiles(imagesFilter);
 
if(children == null) return; // the dir does not exists
 
Arrays.sort(children, fileNameComparator);
 
for(int i = 0; i < children.length; i++) {
if(children[i].isDirectory()) {
writeDir(children[i], null);
buildCache(children[i]);
}
else {
writeSmall(children[i], null);
writeMedium(children[i], null);
}
}
}
 
protected CachedFile getCached(Map cache, File imageFile)
throws IOException
{
CachedFile cached = (CachedFile)cache.get(imageFile.getCanonicalPath());
 
if(cached == null || !cached.getFile().exists()) {
logger.debug("not found in cache");
return null;
}
 
if(cached.getOriginTimestamp() != imageFile.lastModified()) {
cached.getFile().delete();
cache.remove(imageFile.getCanonicalPath());
logger.debug("timestamps dont match");
return null;
}
 
return cached;
}
 
protected boolean writeCached(Map cache, File imageFile, OutputStream out)
throws IOException
{
CachedFile cached = getCached(cache, imageFile);
 
if(cached == null) return false;
 
if(logger.isDebugEnabled())
logger.debug("write cached " + imageFile.getCanonicalPath());
 
if(out != null) {
FileInputStream in = null;
 
try {
in = new FileInputStream(cached.getFile());
FileUtils.copyStreams(in, out);
}
finally {
if(in != null) in.close();
}
}
 
return true;
}
 
protected void cacheThumbnail(Map cache, File imageFile,
BufferedImage thumbnail, String suffix, int width, int height)
throws IOException
{
logger.debug("cache thumbnail " + suffix + " "
+ imageFile.getCanonicalPath());
 
File dir = getCacheFileDir(imageFile);
File cacheFile = new File(dir,
imageFile.getName() + suffix + "." + format);
 
dir.mkdirs();
ImageIO.write(thumbnail, format, cacheFile);
 
cache.put(imageFile.getCanonicalPath(),
new CachedFile(cacheFile, imageFile,
cacheFile.lastModified(), imageFile.lastModified(), width, height));
}
 
public void startup()
throws IOException
{
logger.info("startup");
loadCaches(cacheDir);
logger.info("started");
}
 
protected void loadCaches(File dir)
throws IOException
{
if(logger.isDebugEnabled())
logger.debug("load caches in " + dir.getCanonicalPath());
 
File[] children = dir.listFiles();
String dirEnd = DIR_SUFFIX + "." + format;
String smallEnd = SMALL_SUFFIX + "." + format;
String mediumEnd = MEDIUM_SUFFIX + "." + format;
 
if(children == null) return; // the dir does not exists
 
Arrays.sort(children, fileNameComparator);
 
for(int i = 0; i < children.length; i++) {
if(children[i].isDirectory())
loadCaches(children[i]);
else {
File origin;
Map cache;
 
if(children[i].getName().endsWith(smallEnd)) {
origin = getOriginFile(children[i], SMALL_SUFFIX);
cache = smallCache;
 
if(logger.isDebugEnabled())
logger.debug("load cached small " + children[i].getCanonicalPath()
+ " for " + origin.getCanonicalPath());
}
else if(children[i].getName().endsWith(mediumEnd)) {
origin = getOriginFile(children[i], MEDIUM_SUFFIX);
cache = mediumCache;
 
if(logger.isDebugEnabled())
logger.debug("load cached medium " + children[i].getCanonicalPath()
+ " for " + origin.getCanonicalPath());
}
else if(children[i].getName().endsWith(dirEnd)) {
origin = getOriginFile(children[i], DIR_SUFFIX);
cache = dirCache;
 
if(logger.isDebugEnabled())
logger.debug("load cached dir " + children[i].getCanonicalPath()
+ " for " + origin.getCanonicalPath());
}
else {
if(logger.isInfoEnabled())
logger.warn(
"unknown type of cached " + children[i].getCanonicalPath());
 
continue;
}
 
long originTimestamp = origin.lastModified();
long cachedTimestamp = children[i].lastModified();
int[] sizes = getOriginSize(children[i]);
 
if(origin.exists() && cachedTimestamp >= originTimestamp) {
cache.put(origin.getCanonicalPath(),
new CachedFile(children[i], origin, cachedTimestamp,
originTimestamp, sizes[0], sizes[1]));
 
logger.debug("added");
}
else {
children[i].delete();
 
if(logger.isDebugEnabled())
logger.debug("deleted: " + origin.exists()
+ " " + cachedTimestamp + " " + originTimestamp);
}
}
}
}
 
protected File getOriginFile(File cached, String suffix)
throws IOException
{
String fileEnd = suffix + "." + format;
String fileName = cached.getName();
String cachedPath = cached.getParentFile().getCanonicalPath();
String cacheRoot = cacheDir.getCanonicalPath();
 
fileName = fileName.substring(0, fileName.length() - fileEnd.length());
 
if(!cacheRoot.equals(cachedPath))
if(!cacheRoot.endsWith(File.separator)) cacheRoot += File.separator;
 
return new File(imagesRoot, cachedPath.substring(cacheRoot.length())
+ File.separator + fileName);
}
 
protected File getCacheFileDir(File imageFile)
throws IOException
{
String imagePath = imageFile.getParentFile().getCanonicalPath();
String rootPath = imagesRoot.getCanonicalPath();
 
if(imagePath.equals(rootPath)) return cacheDir;
if(!rootPath.endsWith(File.separator)) rootPath += File.separator;
 
if(!imagePath.startsWith(rootPath))
throw new RuntimeException("Image " + imageFile.getCanonicalPath()
+ " is not under images root " + imagesRoot.getCanonicalPath());
 
return new File(cacheDir, imagePath.substring(rootPath.length()));
}
 
public void writeSmall(File imageFile, OutputStream out)
throws IOException
{
if(logger.isInfoEnabled())
logger.info("write small " + imageFile.getCanonicalPath());
 
if(writeCached(smallCache, imageFile, out)) return;
 
BufferedImage small = createThumbnail(imageFile, smallWidth, smallHeight);
 
if(small != null) {
int sizes[] = calcSizes(
small.getWidth(null), small.getHeight(null), smallWidth, smallHeight);
cacheThumbnail(
smallCache, imageFile, small, SMALL_SUFFIX, sizes[0], sizes[1]);
 
if(out != null) ImageIO.write(small, format, out);
}
}
 
public void writeMedium(File imageFile, OutputStream out)
throws IOException
{
if(logger.isInfoEnabled())
logger.info("write medium " + imageFile.getCanonicalPath());
 
if(writeCached(mediumCache, imageFile, out)) return;
 
BufferedImage medium
= createThumbnail(imageFile, mediumWidth, mediumHeight);
 
if(medium != null) {
int sizes[] = calcSizes(medium.getWidth(null), medium.getHeight(null),
mediumWidth, mediumHeight);
cacheThumbnail(
mediumCache, imageFile, medium, MEDIUM_SUFFIX, sizes[0], sizes[1]);
 
if(out != null) ImageIO.write(medium, format, out);
}
}
 
public void writeDir(File dir, OutputStream out)
throws IOException
{
if(logger.isInfoEnabled())
logger.info("write dir " + dir.getCanonicalPath());
 
if(writeCached(dirCache, dir, out)) return;
 
BufferedImage thumbnail = createDirThumbnail(dir);
 
if(thumbnail != null) {
if(dirTemplateSize == null
|| dirTemplateTimestamp != dirTemplate.lastModified())
{
dirTemplateSize = getOriginSize(dirTemplate);
dirTemplateTimestamp = dirTemplate.lastModified();
}
 
cacheThumbnail(dirCache, dir, thumbnail, DIR_SUFFIX,
dirTemplateSize[0], dirTemplateSize[1]);
 
if(out != null) ImageIO.write(thumbnail, format, out);
}
}
 
synchronized protected BufferedImage createThumbnail(File imageFile,
int width, int height)
throws IOException
{
if(logger.isDebugEnabled())
logger.debug("create thumbnail " + imageFile.getCanonicalPath());
 
Image image = loadImage(imageFile.getCanonicalPath());
// = ImageIO.read(imageFile);
int[] sizes;
 
if(image == null) { // not supported format
logger.warn("unsupported format for origin or operation interrupted");
 
return null;
}
else {
sizes = calcSizes(image.getWidth(null), image.getHeight(null),
width, height);
logger.debug("resize to " + sizes[0] + "x" + sizes[1]);
 
return resizer.resize(image, sizes[0], sizes[1]);
}
}
 
synchronized protected BufferedImage createDirThumbnail(File dir)
throws IOException
{
if(logger.isDebugEnabled())
logger.debug("create dir thumbnail " + dir.getCanonicalPath());
 
Image template = loadImage(dirTemplate.getCanonicalPath());
BufferedImage dirThumbnail;
Graphics graphics;
int count;
File[] firstFiles;
 
if(template == null) { // not supported format
logger.warn("unsupported format for template or operation interrupted");
 
return null;
}
 
dirThumbnail = createBufferedImage(template);
 
graphics = dirThumbnail.getGraphics();
count = dirThumbnailPositions.length;
firstFiles = new File[count];
count = getFirstFiles(dir, count, firstFiles, 0);
 
for(int i = 0; i < count; i++) {
Image image = loadImage(firstFiles[i].getCanonicalPath());
 
if(image == null) { // not supported format
logger.warn("unsupported format for origin or operation interrupted");
 
return null;
}
else {
BufferedImage thumbnail;
int[] sizes;
 
sizes = calcSizes(image.getWidth(null), image.getHeight(null),
dirThumbnailPositions[i].getWidth(),
dirThumbnailPositions[i].getHeight());
 
thumbnail = resizer.resize(image, sizes[0], sizes[1]);
graphics.drawImage(thumbnail,
getXPosition(dirThumbnailPositions[i].getX(),
dirThumbnailPositions[i].getWidth(), sizes[0],
dirThumbnailPositions[i].getHorAlign()),
getYPosition(dirThumbnailPositions[i].getY(),
dirThumbnailPositions[i].getHeight(), sizes[1],
dirThumbnailPositions[i].getVertAlign()),
null);
}
}
 
return dirThumbnail;
}
 
protected Image loadImage(String fileName)
{
// FIXME: probably toolbox reads an image not by every request but
// caches it
Toolkit toolkit = Toolkit.getDefaultToolkit();
Image image = toolkit.getImage(fileName);
 
toolkit.prepareImage(image, -1, -1, null);
 
while(true) {
int status = toolkit.checkImage(image, -1, -1, null);
 
if((status & ImageObserver.ALLBITS) != 0) break;
if((status & ImageObserver.ERROR) != 0) return null;
 
try {
Thread.sleep(100);
}
catch(Exception ex) {
return null;
}
}
 
return image;
}
 
protected int[] calcSizes(int width, int height, int maxWidth, int maxHeight)
{
int[] result = new int[2];
double xRate;
double yRate;
 
if(width == 0 || height == 0) {
result[0] = 0;
result[1] = 0;
return result;
}
 
xRate = (double)maxWidth / (double)width;
yRate = (double)maxHeight / (double)height;
if(xRate >= 1.0 || yRate >= 1.0) {
result[0] = width;
result[1] = height;
}
else if(xRate > yRate) {
result[0] = maxHeight * width / height;
result[1] = maxHeight;
}
else {
result[0] = maxWidth;
result[1] = maxWidth * height / width;
}
 
return result;
}
 
protected int getXPosition(int left, int maxWidth, int width, int align)
{
if(align == ThumbnailPosition.ALIGN_HOR_LEFT)
return left;
else if(align == ThumbnailPosition.ALIGN_HOR_RIGHT)
return left + (maxWidth - width);
else if(align == ThumbnailPosition.ALIGN_HOR_CENTER)
return left + (maxWidth - width) / 2;
else
throw new RuntimeException("Unknown align type: " + align);
}
 
protected int getYPosition(int top, int maxHeight, int height, int align)
{
if(align == ThumbnailPosition.ALIGN_VERT_TOP)
return top;
else if(align == ThumbnailPosition.ALIGN_VERT_BOTTOM)
return top + (maxHeight - height);
else if(align == ThumbnailPosition.ALIGN_VERT_CENTER)
return top + (maxHeight - height) / 2;
else
throw new RuntimeException("Unknown align type: " + align);
}
 
protected int getFirstFiles(File dir, int count, File[] files, int pos)
{
File[] children;
 
if(imagesFilter == null)
children = dir.listFiles();
else
children = dir.listFiles(imagesFilter);
 
if(children == null) return 0; // the dir does not exists
 
Arrays.sort(children, fileNameComparatorRev);
 
for(int i = 0; i < children.length; i++) {
if(children[i].isDirectory())
; //pos = getFirstFiles(children[i], count, files, pos);
else {
files[pos++] = children[i];
}
 
if(pos >= count) break;
}
 
return pos;
}
 
protected BufferedImage createBufferedImage(Image image)
{
if(image == null) return null;
 
int width = image.getWidth(null);
int height = image.getHeight(null);
 
if(width < 1 || height < 1) return null;
 
// get pixels
int[] pixels = new int[width * height];
PixelGrabber pg = new PixelGrabber(image,
0, 0, width, height, pixels, 0, width);
 
try {
pg.grabPixels();
}
catch(InterruptedException e) {
return null;
}
 
if((pg.getStatus() & ImageObserver.ABORT) != 0) return null;
 
// create buffered image
BufferedImage buffered = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
 
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++)
buffered.setRGB(x, y, pixels[y * width + x]);
}
 
return buffered;
}
 
public ImageResizer getResizer()
{
return resizer;
}
 
public void setResizer(ImageResizer resizer)
{
this.resizer = resizer;
}
 
public String getFormat()
{
return format;
}
 
public void setFormat(String format)
{
this.format = format;
}
 
public File getCacheDir()
{
return cacheDir;
}
 
public void setCacheDir(File dir)
{
this.cacheDir = dir;
}
 
public File getImagesRoot()
{
return imagesRoot;
}
 
public void setImagesRoot(File dir)
{
this.imagesRoot = dir;
}
 
public int getSmallWidth()
{
return smallWidth;
}
 
public void setSmallWidth(int width)
{
this.smallWidth = width;
}
 
public int getSmallHeight()
{
return smallHeight;
}
 
public void setSmallHeight(int height)
{
this.smallHeight = height;
}
 
public int getMediumWidth()
{
return mediumWidth;
}
 
public void setMediumWidth(int width)
{
this.mediumWidth = width;
}
 
public int getMediumHeight()
{
return mediumHeight;
}
 
public void setMediumHeight(int height)
{
this.mediumHeight = height;
}
 
public FileFilter getImagesFilter()
{
return imagesFilter;
}
 
public void setImagesFilter(FileFilter filter)
{
this.imagesFilter = filter;
}
 
public File getDirTemplate()
{
return dirTemplate;
}
 
public void setDirTemplate(File dirTemplate)
{
this.dirTemplate = dirTemplate;
}
 
public ThumbnailPosition[] getDirThumbnailPositions()
{
return dirThumbnailPositions;
}
 
public void setDirThumbnailPositions(
ThumbnailPosition[] dirThumbnailPositions)
{
this.dirThumbnailPositions = dirThumbnailPositions;
}
}