/*
* argun 1.0
* Web 2.0 delivery framework
* Copyright (C) 2007 Hammurapi Group
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* URL: http://www.hammurapi.biz
* e-Mail: support@hammurapi.biz
*/
package biz.hammurapi.web;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import org.apache.log4j.Logger;
import biz.hammurapi.config.ChainedContext;
import biz.hammurapi.config.Context;
import biz.hammurapi.config.PropertyParser;
import biz.hammurapi.sql.SQLProcessor;
import biz.hammurapi.web.file.sql.DbFileType;
import biz.hammurapi.web.file.sql.DbFileTypeAction;
import biz.hammurapi.web.file.sql.FileEngine;
import biz.hammurapi.web.file.sql.FileInfo;
import biz.hammurapi.web.menu.MenuNavigator;
import biz.hammurapi.web.security.AuthFilter;
import biz.hammurapi.web.security.User;
/**
* This class constructs links to files from file id's and action names
* @author Pavel Vlasov
*
*/
public class FileNavigator implements ChainedContext {
private static final Logger logger = Logger.getLogger(FileNavigator.class);
private FileEngine engine;
private HashMap fileTypeMap;
/**
* [mime type, action] -> DbFileTypeAction
*/
private HashMap actionMap;
public FileNavigator(SQLProcessor processor) {
this.engine = new FileEngine(processor);
fileTypeMap = new HashMap();
Iterator it = engine.getDbFileType().iterator();
while (it.hasNext()) {
DbFileType dbFileType = (DbFileType) it.next();
fileTypeMap.put(dbFileType.getMimeType(), dbFileType);
}
actionMap = new HashMap();
Iterator ait = engine.getDbFileTypeAction().iterator();
while (ait.hasNext()) {
DbFileTypeAction dfta = (DbFileTypeAction) ait.next();
Collection key = new ArrayList();
key.add(dfta.getMimeType());
key.add(dfta.getName());
actionMap.put(key, dfta);
}
}
/**
* Splits path string and returns file information
* first element shall be file ID. The second element shall be action name.
*/
public Object get(String path, Context chain) {
if (path==null || path.trim().length()==0) {
return null;
}
try {
List cargs = new ArrayList();
for (String[] sa = MenuNavigator.splitAtPipe(path); sa[0]!=null; sa = MenuNavigator.splitAtPipe(sa[1])) {
cargs.add(sa[0]);
}
String[] args = (String[]) cargs.toArray(new String[cargs.size()]);
int fileId = Integer.parseInt(args[0]);
FileInfo fileInfo = engine.getFileInfo(fileId);
// No specifiers - raw read-only URL
if (args.length==1) {
if (fileInfo==null) {
logger.error("Invalid file ID: "+fileId);
return "";
}
return getRoViewUrl(fileInfo, chain);
}
// ro-link - anchor with file name and read-only url
if ("ro-link".equals(args[1])) {
if (fileInfo==null) {
logger.error("Invalid file ID: "+fileId);
return "";
}
String url = getRoViewUrl(fileInfo, chain);
if (url==null) {
return "";
}
return "<a href=\""+url+"\">"+fileInfo.getName()+"</a>";
}
// ro-label - label activated if file exists
if (args.length>2 && "ro-label".equals(args[1])) {
if (fileInfo==null) {
logger.error("Invalid file ID: "+fileId);
return "";
}
String url = getRoViewUrl(fileInfo, chain);
if (url==null) {
return args[2];
}
return "<a href=\""+url+"\">"+args[2]+"</a>";
}
// ro-image - image activated if file exists
if ("ro-image".equals(args[1])) {
if (fileInfo==null) {
logger.error("Invalid file ID: "+fileId);
return "";
}
String url = getRoViewUrl(fileInfo, chain);
if (url==null) {
return "";
}
String caption = args.length>2 ? args[2] : null;
StringBuffer ret = new StringBuffer();
if (!ActionsBase.isBlank(caption)) {
ret.append("<table style=\"width:10px\"><tr><td>");
}
String embellishments = args.length>3 ? args[3] : null;
ret.append("<img src=\"");
ret.append(url);
ret.append("\" ");
String dblClickAction = "Edit";
String dblClickUrl = getActionUrl(fileInfo.getContentType(), dblClickAction, chain);
User user = (User) chain.get("session:"+AuthFilter.USER);
if (dblClickUrl!=null && user!=null && user.hasFilePermission(fileInfo.getId(), dblClickAction)) {
ret.append("ondblclick=\"location.href='");
ret.append(dblClickUrl);
ret.append(dblClickUrl.indexOf("?")==-1 ? "?" : "&");
ret.append("ID=");
ret.append(fileInfo.getId());
ret.append("'\" ");
}
if (ActionsBase.isBlank(embellishments)) {
ret.append("border=\"0\"");
} else {
ret.append(embellishments);
}
ret.append(">");
if (!ActionsBase.isBlank(caption)) {
ret.append("</td></tr><tr><td>");
ret.append(caption);
ret.append("</td></tr></table>");
}
return ret.toString();
}
// action link - first token is action name,
// second token can be 'href' - returns action URL with parameter
// 'link' - link to action. Text is action name or third token
// 'label' - label to action. Text is third token.
// TODO - implement
return null;
} catch (Exception e) {
logger.error("File retrieval failed for path '"+path+"': "+e, e);
return null;
}
}
private String getRoViewUrl(FileInfo fileInfo, Context chain) throws SQLException {
String template = getViewUrlTemplate(fileInfo.getContentType());
if (template==null) {
return null;
}
RequestContext rc = new RequestContext(((RequestContext) chain).getRequest(), (Context) fileInfo);
PropertyParser parser = new PropertyParser(rc, false);
return parser.parse(template);
}
private String getViewUrlTemplate(String mimeType) throws SQLException {
DbFileType fileType = (DbFileType) fileTypeMap.get(mimeType);
if (fileType!=null && fileType.getRoViewUrl()!=null) {
return fileType.getRoViewUrl();
}
int idx = mimeType==null ? -1 : mimeType.indexOf("/");
if (idx==-1) {
fileType = (DbFileType) fileTypeMap.get(FileActions.ROOT_CONTENT_TYPE);
return fileType == null ? null : fileType.getRoViewUrl();
}
return getViewUrlTemplate(mimeType.substring(0, idx));
}
private String getActionUrl(String mimeType, String action, Context chain) {
Collection key = new ArrayList();
key.add(mimeType);
key.add(action);
DbFileTypeAction dfta = (DbFileTypeAction) actionMap.get(key);
if (dfta==null) {
if (FileActions.ROOT_CONTENT_TYPE.equals(mimeType)) {
return null;
}
int idx = mimeType==null ? -1 : mimeType.indexOf("/");
if (idx==-1) {
return getActionUrl(FileActions.ROOT_CONTENT_TYPE, action, chain);
}
return getActionUrl(mimeType.substring(0, idx), action, chain);
} else if (!ActionsBase.isBlank(dfta.getActionXid())) {
return (String) chain.get("xmenu:id:"+dfta.getActionXid()+"|href");
}
return dfta.getActionUrl();
}
}
|