001: /*
002: JSPWiki - a JSP-based WikiWiki clone.
003:
004: Copyright (C) 2004 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.plugin;
021:
022: import java.io.PrintWriter;
023: import java.io.StringWriter;
024: import java.security.Principal;
025: import java.text.MessageFormat;
026: import java.text.SimpleDateFormat;
027: import java.util.*;
028:
029: import org.apache.log4j.Logger;
030:
031: import com.ecyrd.jspwiki.WikiContext;
032: import com.ecyrd.jspwiki.WikiEngine;
033: import com.ecyrd.jspwiki.WikiException;
034: import com.ecyrd.jspwiki.WikiPage;
035: import com.ecyrd.jspwiki.filters.RedirectException;
036: import com.ecyrd.jspwiki.parser.MarkupParser;
037:
038: /**
039: * Provides a handler for bug reports. Still under construction.
040: *
041: * <ul>
042: * <li>"title" = title of the bug. This is required. If it is empty (as in "")
043: * it is a signal to the handler to return quietly.</li>
044: * </ul>
045: *
046: * @author Janne Jalkanen
047: */
048: public class BugReportHandler implements WikiPlugin {
049: private static Logger log = Logger
050: .getLogger(BugReportHandler.class);
051:
052: public static final String TITLE = "title";
053: public static final String DESCRIPTION = "description";
054: public static final String VERSION = "version";
055: public static final String MAPPINGS = "map";
056: public static final String PAGE = "page";
057:
058: public static final String DEFAULT_DATEFORMAT = "dd-MMM-yyyy HH:mm:ss zzz";
059:
060: public String execute(WikiContext context, Map params)
061: throws PluginException {
062: String title;
063: String description;
064: String version;
065: String submitter = null;
066: SimpleDateFormat format = new SimpleDateFormat(
067: DEFAULT_DATEFORMAT);
068: ResourceBundle rb = context
069: .getBundle(WikiPlugin.CORE_PLUGINS_RESOURCEBUNDLE);
070:
071: title = (String) params.get(TITLE);
072: description = (String) params.get(DESCRIPTION);
073: version = (String) params.get(VERSION);
074:
075: Principal wup = context.getCurrentUser();
076:
077: if (wup != null) {
078: submitter = wup.getName();
079: }
080:
081: if (title == null)
082: throw new PluginException(rb
083: .getString("bugreporthandler.titlerequired"));
084: if (title.length() == 0)
085: return "";
086:
087: if (description == null)
088: description = "";
089: if (version == null)
090: version = "unknown";
091:
092: Properties mappings = parseMappings((String) params
093: .get(MAPPINGS));
094:
095: //
096: // Start things
097: //
098:
099: try {
100: StringWriter str = new StringWriter();
101: PrintWriter out = new PrintWriter(str);
102:
103: Date d = new Date();
104:
105: //
106: // Outputting of basic data
107: //
108: out.println("|" + mappings.getProperty(TITLE, "Title")
109: + "|" + title);
110: out.println("|" + mappings.getProperty("date", "Date")
111: + "|" + format.format(d));
112: out.println("|" + mappings.getProperty(VERSION, "Version")
113: + "|" + version);
114: if (submitter != null) {
115: out.println("|"
116: + mappings
117: .getProperty("submitter", "Submitter")
118: + "|" + submitter);
119: }
120:
121: //
122: // Outputting the other parameters added to this.
123: //
124: for (Iterator i = params.entrySet().iterator(); i.hasNext();) {
125: Map.Entry entry = (Map.Entry) i.next();
126:
127: if (entry.getKey().equals(TITLE)
128: || entry.getKey().equals(DESCRIPTION)
129: || entry.getKey().equals(VERSION)
130: || entry.getKey().equals(MAPPINGS)
131: || entry.getKey().equals(PAGE)
132: || entry.getKey().toString().startsWith("_")) {
133: // Ignore this
134: } else {
135: //
136: // If no mapping has been defined, just ignore
137: // it.
138: //
139: String head = mappings.getProperty((String) entry
140: .getKey(), (String) entry.getKey());
141: if (head.length() > 0) {
142: out
143: .println("|" + head + "|"
144: + entry.getValue());
145: }
146: }
147: }
148:
149: out.println();
150: out.println(description);
151:
152: out.close();
153:
154: //
155: // Now create a new page for this bug report
156: //
157: String pageName = findNextPage(context, title,
158: (String) params.get(PAGE));
159:
160: WikiPage newPage = new WikiPage(context.getEngine(),
161: pageName);
162: WikiContext newContext = (WikiContext) context.clone();
163: newContext.setPage(newPage);
164:
165: context.getEngine().saveText(newContext, str.toString());
166:
167: MessageFormat formatter = new MessageFormat("");
168: formatter
169: .applyPattern(rb.getString("bugreporthandler.new"));
170: String[] args = { "<a href=\""
171: + context.getViewURL(pageName) + "\">" + pageName
172: + "</a>" };
173:
174: return formatter.format(args);
175: } catch (RedirectException e) {
176: log.info("Saving not allowed, reason: '" + e.getMessage()
177: + "', can't redirect to " + e.getRedirect());
178:
179: throw new PluginException("Saving not allowed, reason: "
180: + e.getMessage());
181: } catch (WikiException e) {
182: log.error("Unable to save page!", e);
183:
184: return rb.getString("bugreporthandler.unable");
185: }
186: }
187:
188: /**
189: * Finds a free page name for adding the bug report. Tries to construct a page,
190: * and if it's found, adds a number to it and tries again.
191: */
192: private synchronized String findNextPage(WikiContext context,
193: String title, String baseName) {
194: String basicPageName = ((baseName != null) ? baseName : "Bug")
195: + MarkupParser.cleanLink(title);
196:
197: WikiEngine engine = context.getEngine();
198:
199: String pageName = basicPageName;
200: long lastbug = 2;
201:
202: while (engine.pageExists(pageName)) {
203: pageName = basicPageName + lastbug++;
204: }
205:
206: return pageName;
207: }
208:
209: /**
210: * Just parses a mappings list in the form of "a=b;b=c;c=d".
211: * <p>
212: * FIXME: Should probably be in TextUtil or somewhere.
213: */
214: private Properties parseMappings(String mappings) {
215: Properties props = new Properties();
216:
217: if (mappings == null)
218: return props;
219:
220: StringTokenizer tok = new StringTokenizer(mappings, ";");
221:
222: while (tok.hasMoreTokens()) {
223: String t = tok.nextToken();
224:
225: int colon = t.indexOf("=");
226:
227: String key;
228: String value;
229:
230: if (colon > 0) {
231: key = t.substring(0, colon);
232: value = t.substring(colon + 1);
233: } else {
234: key = t;
235: value = "";
236: }
237:
238: props.setProperty(key, value);
239: }
240:
241: return props;
242: }
243: }
|