001: /*
002: JSPWiki - a JSP-based WikiWiki clone.
003:
004: Copyright (C) 2001 Janne Jalkanen (Janne.Jalkanen@iki.fi)
005:
006: This program is free software; you can redistribute it and/or modify
007: it under the terms of the GNU Lesser General Public License as published by
008: the Free Software Foundation; either version 2.1 of the License, or
009: (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
014: GNU Lesser General Public License for more details.
015:
016: You should have received a copy of the GNU Lesser General Public License
017: along with this program; if not, write to the Free Software
018: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: */
020: package com.ecyrd.jspwiki;
021:
022: import java.util.HashMap;
023: import java.util.Map;
024: import java.util.ResourceBundle;
025:
026: import javax.servlet.http.HttpSession;
027: import javax.servlet.http.HttpServletRequest;
028: import javax.servlet.http.HttpServletResponse;
029:
030: import com.ecyrd.jspwiki.auth.UserProfile;
031:
032: import com.sun.portal.app.wiki.WikiPortletContext;
033:
034: import com.iplanet.am.sdk.*;
035: import com.iplanet.sso.*;
036:
037: /**
038: * Provides state information throughout the processing of a page. A
039: * WikiContext is born when the JSP pages that are the main entry
040: * points, are invoked. The JSPWiki engine creates the new
041: * WikiContext, which basically holds information about the page, the
042: * handling engine, and in which context (view, edit, etc) the
043: * call was done.
044: * <P>
045: * A WikiContext also provides request-specific variables, which can
046: * be used to communicate between plugins on the same page, or
047: * between different instances of the same plugin. A WikiContext
048: * variable is valid until the processing of the page has ended. For
049: * an example, please see the Counter plugin.
050: *
051: * @see com.ecyrd.jspwiki.plugin.Counter
052: *
053: * @author Janne Jalkanen
054: */
055: public class WikiContext implements Cloneable {
056: WikiPage m_page;
057: WikiEngine m_engine;
058: String m_requestContext = VIEW;
059: String m_template = "default";
060: ResourceBundle m_templateBundle = null;
061: String m_namespace = ""; // XXX use the application name as default?
062:
063: static ThreadLocal m_wikiNameTL = new ThreadLocal();
064:
065: Map m_variableMap = new HashMap();
066:
067: HttpServletRequest m_request = null;
068: HttpServletResponse m_response = null;
069: static ThreadLocal m_req_tl = new ThreadLocal();
070:
071: UserProfile m_currentUser;
072:
073: /** The VIEW context - the user just wants to view the page
074: contents. */
075: public static final String VIEW = "view";
076:
077: /** The EDIT context - the user is editing the page. */
078: public static final String EDIT = "edit";
079:
080: /** User is preparing for a login/authentication. */
081: public static final String LOGIN = "login";
082:
083: /** User is viewing a DIFF between the two versions of the page. */
084: public static final String DIFF = "diff";
085:
086: /** User is viewing page history. */
087: public static final String INFO = "info";
088:
089: /** User is previewing the changes he just made. */
090: public static final String PREVIEW = "preview";
091:
092: /** User has an internal conflict, and does quite not know what to
093: do. Please provide some counseling. */
094: public static final String CONFLICT = "conflict";
095:
096: /** An error has been encountered and the user needs to be informed. */
097: public static final String ERROR = "error";
098:
099: public static final String UPLOAD = "upload";
100:
101: public static final String COMMENT = "comment";
102: public static final String FIND = "find";
103:
104: public static final String PREFS = "prefs";
105: public static final String DELETE = "del";
106: public static final String ATTACH = "att";
107: public static final String RSS = "rss";
108:
109: public static final String NONE = ""; // This is not a JSPWiki context, use it to access static files
110:
111: /**
112: * Create a new WikiContext.
113: *
114: * @param engine The WikiEngine that is handling the request.
115: * @param pagename The name of the page. A new WikiPage is
116: * created.
117: * @deprecated
118: */
119:
120: // Changed to private - nobody should ever call this method.
121: private WikiContext(WikiEngine engine, String pagename) {
122: m_page = new WikiPage(pagename);
123: m_engine = engine;
124: }
125:
126: /**
127: * Create a new WikiContext for the given WikiPage.
128: *
129: * @param engine The WikiEngine that is handling the request.
130: * @param page The WikiPage. If you want to create a
131: * WikiContext for an older version of a page, you must use this
132: * constructor.
133: */
134: public WikiContext(WikiEngine engine, WikiPage page) {
135: m_page = page;
136: m_engine = engine;
137: }
138:
139: /**
140: * Returns the handling engine.
141: */
142: public WikiEngine getEngine() {
143: return m_engine;
144: }
145:
146: /**
147: * Returns the page that is being handled.
148: */
149: public WikiPage getPage() {
150: return m_page;
151: }
152:
153: /**
154: * Sets the page that is being handled.
155: *
156: * @since 2.1.37.
157: */
158: public void setPage(WikiPage page) {
159: m_page = page;
160: }
161:
162: /**
163: * Returns the request context.
164: */
165: public String getRequestContext() {
166: return m_requestContext;
167: }
168:
169: /**
170: * Sets the request context. See above for the different
171: * request contexts (VIEW, EDIT, etc.)
172: *
173: * @param arg The request context (one of the predefined contexts.)
174: */
175: public void setRequestContext(String arg) {
176: m_requestContext = arg;
177: }
178:
179: /**
180: * Gets a previously set variable.
181: *
182: * @param key The variable name.
183: * @return The variable contents.
184: */
185: public Object getVariable(String key) {
186: return m_variableMap.get(key);
187: }
188:
189: /**
190: * Sets a variable. The variable is valid while the WikiContext is valid,
191: * i.e. while page processing continues. The variable data is discarded
192: * once the page processing is finished.
193: *
194: * @param key The variable name.
195: * @param data The variable value.
196: */
197: public void setVariable(String key, Object data) {
198: m_variableMap.put(key, data);
199: }
200:
201: /**
202: * Gets a previously set private session attribute.
203: * Private attributes are visible to the current wiki context only.
204: *
205: * @param key The attribute name.
206: * @return The attribute value.
207: */
208: public Object getPrivateSessionAttribute(String key) {
209: // XXX perhaps should use engine, variable manager (and scopes?)
210: Object o = null;
211: HttpSession session = m_request.getSession();
212: if (session != null)
213: o = session.getAttribute(getNamespace() + "." + key);
214: return o;
215: }
216:
217: /**
218: * Sets a private session attribute.
219: * Private attributes are visible to the current wiki context only.
220: * The attribute is valid while the HttpSession is valid,
221: * The attribute data is discarded once the session is finished.
222: *
223: * @param key The attribute name.
224: * @param data The attribute value.
225: */
226: public void setPrivateSessionAttribute(String key, Object data) {
227: HttpSession session = m_request.getSession(true);
228: session.setAttribute(getNamespace() + "." + key, data);
229: }
230:
231: /**
232: * Gets the wiki instance namespace for this wiki context.
233: *
234: * @return The wiki instance namespace.
235: */
236: public String getNamespace() {
237: String ns = WikiPortletContext.getNamespace();
238: if (ns != null)
239: return ns;
240: else
241: return m_namespace;
242: }
243:
244: /**
245: * Sets an optional wiki instance namespace for this wiki context.
246: *
247: * The data is discarded once the context is finished.
248: *
249: * @param namespace The namespace.
250: */
251: public void setNamespace(String namespace) // XXX not used, won't work
252: {
253: m_namespace = namespace;
254: }
255:
256: /**
257: * This method will safely return any HTTP parameters that
258: * might have been defined. You should use this method instead
259: * of peeking directly into the result of getHttpRequest(), since
260: * this method is smart enough to do all of the right things,
261: * figure out UTF-8 encoded parameters, etc.
262: *
263: * @since 2.0.13.
264: * @param paramName Parameter name to look for.
265: * @return HTTP parameter, or null, if no such parameter existed.
266: */
267: public String getHttpParameter(String paramName) {
268: String result = null;
269:
270: if (m_request != null) {
271: result = m_engine.safeGetParameter(m_request, paramName);
272: }
273:
274: return result;
275: }
276:
277: /**
278: * If the request originated from a HTTP server,
279: * the HTTP request is stored here.
280: *
281: * @param req The HTTP servlet request.
282: *
283: * @since 2.0.13.
284: */
285: public void setHttpRequest(HttpServletRequest req) {
286: m_request = req;
287: setHttpRequestForThread(req);
288: }
289:
290: /**
291: * If the request did originate from a HTTP request,
292: * then the HTTP request can be fetched here. However, it the request
293: * did NOT originate from a HTTP request, then this method will
294: * return null, and YOU SHOULD CHECK FOR IT!
295: *
296: * @return Null, if no HTTP request was done.
297: * @since 2.0.13.
298: */
299: public HttpServletRequest getHttpRequest() {
300: return m_request;
301: }
302:
303: public static HttpServletRequest getHttpRequestForThread() {
304: return (HttpServletRequest) m_req_tl.get();
305: }
306:
307: public static void setHttpRequestForThread(HttpServletRequest req) {
308: m_req_tl.set(req);
309: }
310:
311: public void setHttpResponse(HttpServletResponse res) {
312: m_response = res;
313: }
314:
315: public HttpServletResponse getHttpResponse() {
316: return m_response;
317: }
318:
319: public void sendRedirect(String location)
320: throws java.io.IOException {
321: if (WikiPortletContext.isActive()) {
322: WikiPortletContext.put("wiki.redirect", location);
323: } else {
324: m_response.sendRedirect(location);
325: }
326: }
327:
328: /**
329: * Sets the template to be used for this request.
330: * @since 2.1.15.
331: */
332: public void setTemplate(String dir) {
333: m_template = dir;
334: }
335:
336: /**
337: * Gets the template that is to be used throughout this request.
338: * @since 2.1.15.
339: */
340: public String getTemplate() {
341: return m_template;
342: }
343:
344: /**
345: * Sets the template resourece bundle that is to be used throughout this request.
346: */
347: public void setTemplateBundle(ResourceBundle rb) {
348: m_templateBundle = rb;
349: }
350:
351: /**
352: * Gets the template resourece bundle that is to be used throughout this request.
353: */
354: public ResourceBundle getTemplateBundle() {
355: return m_templateBundle;
356: }
357:
358: /**
359: * Translates key using the current template's resourece bundle.
360: */
361: public String translate(String key) {
362: if (key == null || m_templateBundle == null)
363: return key;
364: else
365: return m_templateBundle.getString(key);
366: }
367:
368: /**
369: * Sets the current user.
370: */
371: public void setCurrentUser(UserProfile wup) {
372: m_currentUser = wup;
373: }
374:
375: /**
376: * Gets the current user. May return null, in case the current
377: * user has not yet been determined; or this is an internal system.
378: */
379: public UserProfile getCurrentUser() {
380: return m_currentUser;
381: }
382:
383: public String getViewURL(String page) {
384: return getURL(VIEW, page, null);
385: }
386:
387: public String getURL(String context, String page) {
388: return getURL(context, page, null);
389: }
390:
391: /**
392: * Returns an URL from a page
393: */
394: public String getURL(String context, String page, String params) {
395: // FIXME: is rather slow
396: return m_engine.getURL(context, page, params, "absolute"
397: .equals(m_engine.getVariable(this ,
398: WikiEngine.PROP_REFSTYLE)));
399: }
400:
401: /**
402: * Returns a shallow clone of the WikiContext.
403: *
404: * @since 2.1.37.
405: */
406: public Object clone() {
407: WikiContext copy = new WikiContext(m_engine, m_page);
408:
409: copy.m_requestContext = m_requestContext;
410: copy.m_template = m_template;
411: copy.m_variableMap = m_variableMap;
412: copy.m_request = m_request;
413: copy.m_response = m_response;
414: copy.m_currentUser = m_currentUser;
415: copy.m_namespace = m_namespace;
416: copy.m_templateBundle = m_templateBundle;
417:
418: return copy;
419: }
420:
421: public static void setWikiName(String ps) {
422: m_wikiNameTL.set(ps);
423: }
424:
425: public static String getWikiName() {
426: return (String) m_wikiNameTL.get();
427: }
428:
429: public String getUserCommonName(String userid) {
430: return m_engine.getUserManager().getUserCommonName(userid);
431: }
432:
433: }
|