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 javax.naming.InitialContext;
026: import javax.naming.NamingException;
027: import javax.servlet.http.HttpServletRequest;
028: import javax.servlet.http.HttpSession;
029:
030: import org.apache.commons.codec.EncoderException;
031: import org.apache.commons.codec.net.URLCodec;
032: import org.apache.log4j.Logger;
033:
034: import biz.hammurapi.config.BeanContext;
035: import biz.hammurapi.config.ChainedContext;
036: import biz.hammurapi.config.Context;
037: import biz.hammurapi.config.MutableContext;
038: import biz.hammurapi.config.PropertyParser;
039: import biz.hammurapi.config.Wrapper;
040: import biz.hammurapi.web.menu.Menu;
041: import bsh.EvalError;
042: import bsh.Interpreter;
043:
044: /**
045: * Collects contexts from request attributes and uses them as prefixes.
046: * Predefined prefixes:
047: * param:<name> - request parameter
048: * multiparam:<name> - request parameter with multiple values as a collection
049: * request:<name> - request attribute
050: * session:<name> - session attribute
051: * @author Pavel Vlasov
052: *
053: * @version $Revision$
054: */
055: public class RequestContext implements MutableContext {
056: private static final Logger logger = Logger
057: .getLogger(RequestContext.class);
058: private HttpServletRequest request;
059: private URLCodec codec = new URLCodec();
060: private InitialContext ictx;
061: private Context chain;
062: private static int ajaxCounter;
063:
064: public RequestContext(final HttpServletRequest request) {
065: this (request, null);
066: }
067:
068: public HttpServletRequest getRequest() {
069: return request;
070: }
071:
072: /**
073: * @param request - Request
074: * @param chain
075: */
076: public RequestContext(final HttpServletRequest request,
077: Context chain) {
078: this .request = request;
079: this .chain = chain;
080: }
081:
082: public Object get(String name) {
083: Object ret = _get(name);
084: if (ret instanceof WebWrapper) {
085: return ((WebWrapper) ret).get(request);
086: }
087:
088: if (ret instanceof Wrapper) {
089: return ((Wrapper) ret).getMaster();
090: }
091:
092: return ret;
093: }
094:
095: private Object _get(String name) {
096: if (name == null) {
097: return null;
098: }
099:
100: // Context path is very often used.
101: // Normalized - without trailing /
102: if ("context-path".equals(name)) {
103: String contextPath = request.getContextPath();
104: if (contextPath == null || "/".equals(contextPath)) {
105: return "";
106: }
107:
108: if (contextPath.endsWith("/")) {
109: return contextPath.substring(0,
110: contextPath.length() - 1);
111: }
112:
113: return contextPath;
114: }
115:
116: if ("context-url".equals(name)) {
117: String requestUrl = request.getRequestURL().toString();
118: int start = requestUrl.indexOf("//") + 2;
119:
120: int idx = requestUrl.indexOf("/", start);
121: if (idx == -1) {
122: return requestUrl;
123: }
124:
125: return requestUrl.substring(0, idx) + _get("context-path");
126: }
127:
128: if ("session".equals(name)) {
129: return request.getSession();
130: }
131:
132: if ("request".equals(name)) {
133: return request;
134: }
135:
136: int idx = name.indexOf(":");
137: if (idx == -1) {
138: return chain == null ? null : chain.get(name);
139: }
140:
141: String nameSpace = name.substring(0, idx);
142: String key = name.substring(idx + 1);
143: if ("param".equals(nameSpace)) {
144: return request.getParameter(key);
145: }
146:
147: if ("multiparam".equals(nameSpace)) {
148: StringBuffer sb = new StringBuffer();
149: String[] values = request.getParameterValues(key);
150: for (int i = 0; values != null && i < values.length; ++i) {
151: if (i > 0) {
152: sb.append(",");
153: }
154: sb.append(values[i]);
155: }
156: return sb.toString();
157: }
158:
159: if ("request".equals(nameSpace)) {
160: return request.getAttribute(key);
161: }
162:
163: if ("rqst".equals(nameSpace)) {
164: return new BeanContext(request).get(key);
165: }
166:
167: if ("session".equals(nameSpace)) {
168: return request.getSession().getAttribute(key);
169: }
170:
171: if ("encode".equals(nameSpace)) {
172: Object ret = get(key);
173: try {
174: return ret == null ? null : codec
175: .encode(ret.toString());
176: } catch (EncoderException e) {
177: throw new HammurapiWebRuntimeException(
178: "Could not encode '" + ret + "': " + e, e);
179: }
180: }
181:
182: if ("escapeHtml".equals(nameSpace)) {
183: Object ret = get(key);
184: return ret == null ? null : Menu.escapeHtml(ret.toString());
185: }
186:
187: if ("silent".equals(nameSpace)) {
188: Object ret = get(key);
189: return ret == null ? "" : ret;
190: }
191:
192: if ("eval".equals(nameSpace)) {
193: Interpreter interpreter = new Interpreter();
194: try {
195: interpreter.set("request", request);
196: interpreter.set("requestContext", this );
197: return interpreter.eval(key);
198: } catch (EvalError e) {
199: logger.error("Evaluation failed: " + key + ", " + e, e);
200: }
201: }
202:
203: if ("encode-url".equals(nameSpace)) {
204: try {
205: return codec.encode(key);
206: } catch (EncoderException e) {
207: throw new HammurapiWebRuntimeException(
208: "Could not encode '" + key + "': " + e, e);
209: }
210: }
211:
212: if ("jndi".equals(nameSpace)) {
213: try {
214: if (ictx == null) {
215: ictx = new InitialContext();
216: }
217: return ictx.lookup(key);
218: } catch (NamingException e) {
219: throw new HammurapiWebRuntimeException(
220: "Naming exception while looking up '" + key
221: + "': " + e, e);
222: }
223: }
224:
225: if ("ajax".equals(nameSpace)) {
226: StringBuffer sb = new StringBuffer("<DIV id=\"");
227: String divId = "ajax";
228: synchronized (getClass()) {
229: divId += ++ajaxCounter;
230: }
231: sb.append(divId);
232: sb.append("\"> </DIV>\n");
233:
234: sb.append("<script language=\"JavaScript\">\n");
235: sb.append("ajax_loadContent('");
236: sb.append(divId);
237: sb.append("', '");
238:
239: PropertyParser ps = new PropertyParser(this , false);
240: sb.append(ps.parse(key));
241: sb.append("')\n</script>");
242: return sb.toString();
243: }
244:
245: Object o = request.getAttribute(nameSpace);
246: if (o instanceof ChainedContext) {
247: return ((ChainedContext) o).get(key, this );
248: }
249:
250: if (o instanceof Context) {
251: return ((Context) o).get(key);
252: }
253:
254: HttpSession session = request.getSession(false);
255: o = session == null ? null : session.getAttribute(nameSpace);
256: if (o instanceof ChainedContext) {
257: return ((ChainedContext) o).get(key, this );
258: }
259:
260: if (o instanceof Context) {
261: return ((Context) o).get(key);
262: }
263:
264: return chain == null ? null : chain.get(name);
265: }
266:
267: /**
268: * Sets request attribute
269: */
270: public void set(String name, Object value) {
271: request.setAttribute(name, value);
272: }
273:
274: public void remove(String name) {
275: request.removeAttribute(name);
276:
277: }
278: }
|