/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/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"); |
} |
} |