001: /*
002: * argun 1.0
003: * Web 2.0 delivery framework
004: * Copyright (C) 2007 Hammurapi Group
005: *
006: * This program is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2 of the License, or (at your option) any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: *
020: * URL: http://www.hammurapi.biz
021: * e-Mail: support@hammurapi.biz
022: */
023: package biz.hammurapi.web;
024:
025: import java.sql.SQLException;
026: import java.util.ArrayList;
027: import java.util.Collection;
028: import java.util.HashMap;
029: import java.util.Iterator;
030: import java.util.List;
031:
032: import org.apache.log4j.Logger;
033:
034: import biz.hammurapi.config.ChainedContext;
035: import biz.hammurapi.config.Context;
036: import biz.hammurapi.config.PropertyParser;
037: import biz.hammurapi.sql.SQLProcessor;
038: import biz.hammurapi.web.file.sql.DbFileType;
039: import biz.hammurapi.web.file.sql.DbFileTypeAction;
040: import biz.hammurapi.web.file.sql.FileEngine;
041: import biz.hammurapi.web.file.sql.FileInfo;
042: import biz.hammurapi.web.menu.MenuNavigator;
043: import biz.hammurapi.web.security.AuthFilter;
044: import biz.hammurapi.web.security.User;
045:
046: /**
047: * This class constructs links to files from file id's and action names
048: * @author Pavel Vlasov
049: *
050: */
051: public class FileNavigator implements ChainedContext {
052: private static final Logger logger = Logger
053: .getLogger(FileNavigator.class);
054:
055: private FileEngine engine;
056: private HashMap fileTypeMap;
057:
058: /**
059: * [mime type, action] -> DbFileTypeAction
060: */
061: private HashMap actionMap;
062:
063: public FileNavigator(SQLProcessor processor) {
064: this .engine = new FileEngine(processor);
065: fileTypeMap = new HashMap();
066: Iterator it = engine.getDbFileType().iterator();
067: while (it.hasNext()) {
068: DbFileType dbFileType = (DbFileType) it.next();
069: fileTypeMap.put(dbFileType.getMimeType(), dbFileType);
070: }
071:
072: actionMap = new HashMap();
073: Iterator ait = engine.getDbFileTypeAction().iterator();
074: while (ait.hasNext()) {
075: DbFileTypeAction dfta = (DbFileTypeAction) ait.next();
076: Collection key = new ArrayList();
077: key.add(dfta.getMimeType());
078: key.add(dfta.getName());
079: actionMap.put(key, dfta);
080: }
081: }
082:
083: /**
084: * Splits path string and returns file information
085: * first element shall be file ID. The second element shall be action name.
086: */
087: public Object get(String path, Context chain) {
088: if (path == null || path.trim().length() == 0) {
089: return null;
090: }
091:
092: try {
093: List cargs = new ArrayList();
094: for (String[] sa = MenuNavigator.splitAtPipe(path); sa[0] != null; sa = MenuNavigator
095: .splitAtPipe(sa[1])) {
096: cargs.add(sa[0]);
097: }
098:
099: String[] args = (String[]) cargs.toArray(new String[cargs
100: .size()]);
101:
102: int fileId = Integer.parseInt(args[0]);
103: FileInfo fileInfo = engine.getFileInfo(fileId);
104:
105: // No specifiers - raw read-only URL
106: if (args.length == 1) {
107: if (fileInfo == null) {
108: logger.error("Invalid file ID: " + fileId);
109: return "";
110: }
111: return getRoViewUrl(fileInfo, chain);
112: }
113:
114: // ro-link - anchor with file name and read-only url
115: if ("ro-link".equals(args[1])) {
116: if (fileInfo == null) {
117: logger.error("Invalid file ID: " + fileId);
118: return "";
119: }
120: String url = getRoViewUrl(fileInfo, chain);
121: if (url == null) {
122: return "";
123: }
124: return "<a href=\"" + url + "\">" + fileInfo.getName()
125: + "</a>";
126: }
127:
128: // ro-label - label activated if file exists
129: if (args.length > 2 && "ro-label".equals(args[1])) {
130: if (fileInfo == null) {
131: logger.error("Invalid file ID: " + fileId);
132: return "";
133: }
134: String url = getRoViewUrl(fileInfo, chain);
135: if (url == null) {
136: return args[2];
137: }
138: return "<a href=\"" + url + "\">" + args[2] + "</a>";
139: }
140:
141: // ro-image - image activated if file exists
142: if ("ro-image".equals(args[1])) {
143: if (fileInfo == null) {
144: logger.error("Invalid file ID: " + fileId);
145: return "";
146: }
147: String url = getRoViewUrl(fileInfo, chain);
148: if (url == null) {
149: return "";
150: }
151: String caption = args.length > 2 ? args[2] : null;
152: StringBuffer ret = new StringBuffer();
153: if (!ActionsBase.isBlank(caption)) {
154: ret.append("<table style=\"width:10px\"><tr><td>");
155: }
156: String embellishments = args.length > 3 ? args[3]
157: : null;
158: ret.append("<img src=\"");
159: ret.append(url);
160: ret.append("\" ");
161:
162: String dblClickAction = "Edit";
163: String dblClickUrl = getActionUrl(fileInfo
164: .getContentType(), dblClickAction, chain);
165: User user = (User) chain.get("session:"
166: + AuthFilter.USER);
167: if (dblClickUrl != null
168: && user != null
169: && user.hasFilePermission(fileInfo.getId(),
170: dblClickAction)) {
171: ret.append("ondblclick=\"location.href='");
172: ret.append(dblClickUrl);
173: ret.append(dblClickUrl.indexOf("?") == -1 ? "?"
174: : "&");
175: ret.append("ID=");
176: ret.append(fileInfo.getId());
177: ret.append("'\" ");
178: }
179:
180: if (ActionsBase.isBlank(embellishments)) {
181: ret.append("border=\"0\"");
182: } else {
183: ret.append(embellishments);
184: }
185: ret.append(">");
186: if (!ActionsBase.isBlank(caption)) {
187: ret.append("</td></tr><tr><td>");
188: ret.append(caption);
189: ret.append("</td></tr></table>");
190: }
191: return ret.toString();
192: }
193:
194: // action link - first token is action name,
195: // second token can be 'href' - returns action URL with parameter
196: // 'link' - link to action. Text is action name or third token
197: // 'label' - label to action. Text is third token.
198: // TODO - implement
199:
200: return null;
201: } catch (Exception e) {
202: logger.error("File retrieval failed for path '" + path
203: + "': " + e, e);
204: return null;
205: }
206: }
207:
208: private String getRoViewUrl(FileInfo fileInfo, Context chain)
209: throws SQLException {
210: String template = getViewUrlTemplate(fileInfo.getContentType());
211: if (template == null) {
212: return null;
213: }
214:
215: RequestContext rc = new RequestContext(((RequestContext) chain)
216: .getRequest(), (Context) fileInfo);
217: PropertyParser parser = new PropertyParser(rc, false);
218: return parser.parse(template);
219: }
220:
221: private String getViewUrlTemplate(String mimeType)
222: throws SQLException {
223: DbFileType fileType = (DbFileType) fileTypeMap.get(mimeType);
224: if (fileType != null && fileType.getRoViewUrl() != null) {
225: return fileType.getRoViewUrl();
226: }
227:
228: int idx = mimeType == null ? -1 : mimeType.indexOf("/");
229:
230: if (idx == -1) {
231: fileType = (DbFileType) fileTypeMap
232: .get(FileActions.ROOT_CONTENT_TYPE);
233: return fileType == null ? null : fileType.getRoViewUrl();
234: }
235:
236: return getViewUrlTemplate(mimeType.substring(0, idx));
237: }
238:
239: private String getActionUrl(String mimeType, String action,
240: Context chain) {
241: Collection key = new ArrayList();
242: key.add(mimeType);
243: key.add(action);
244: DbFileTypeAction dfta = (DbFileTypeAction) actionMap.get(key);
245: if (dfta == null) {
246: if (FileActions.ROOT_CONTENT_TYPE.equals(mimeType)) {
247: return null;
248: }
249:
250: int idx = mimeType == null ? -1 : mimeType.indexOf("/");
251:
252: if (idx == -1) {
253: return getActionUrl(FileActions.ROOT_CONTENT_TYPE,
254: action, chain);
255: }
256:
257: return getActionUrl(mimeType.substring(0, idx), action,
258: chain);
259: } else if (!ActionsBase.isBlank(dfta.getActionXid())) {
260: return (String) chain.get("xmenu:id:" + dfta.getActionXid()
261: + "|href");
262: }
263:
264: return dfta.getActionUrl();
265: }
266: }
|