001/* 002 Licensed to the Apache Software Foundation (ASF) under one 003 or more contributor license agreements. See the NOTICE file 004 distributed with this work for additional information 005 regarding copyright ownership. The ASF licenses this file 006 to you under the Apache License, Version 2.0 (the 007 "License"); you may not use this file except in compliance 008 with the License. You may obtain a copy of the License at 009 010 http://www.apache.org/licenses/LICENSE-2.0 011 012 Unless required by applicable law or agreed to in writing, 013 software distributed under the License is distributed on an 014 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 KIND, either express or implied. See the License for the 016 specific language governing permissions and limitations 017 under the License. 018 */ 019package org.apache.wiki.plugin; 020 021import java.io.PrintWriter; 022import java.io.StringWriter; 023import java.security.Principal; 024import java.text.MessageFormat; 025import java.text.SimpleDateFormat; 026import java.util.*; 027 028import org.apache.log4j.Logger; 029import org.apache.wiki.WikiContext; 030import org.apache.wiki.WikiEngine; 031import org.apache.wiki.WikiPage; 032import org.apache.wiki.api.exceptions.PluginException; 033import org.apache.wiki.api.exceptions.RedirectException; 034import org.apache.wiki.api.exceptions.WikiException; 035import org.apache.wiki.api.plugin.WikiPlugin; 036import org.apache.wiki.parser.MarkupParser; 037import org.apache.wiki.preferences.Preferences; 038 039/** 040 * Provides a handler for bug reports. Still under construction. 041 * 042 * <p>Parameters : </p> 043 * <ul> 044 * <li><b>title</b> - title of the bug, this is required. If it is empty (as in "") it is a signal to the handler to return quietly.</li> 045 * <li><b>description</b> - description of the bug.</li> 046 * <li><b>version</b> - version</li> 047 * <li><b>map</b> - I have no idea </li> 048 * <li><b>page</b> - The name of the page to be created for this bug report </li> 049 * </ul> 050 * 051 */ 052public class BugReportHandler 053 implements WikiPlugin 054{ 055 private static Logger log = Logger.getLogger( BugReportHandler.class ); 056 057 /** Parameter name for setting the title. Value is <tt>{@value}</tt>. */ 058 public static final String PARAM_TITLE = "title"; 059 /** Parameter name for setting the description. Value is <tt>{@value}</tt>. */ 060 public static final String PARAM_DESCRIPTION = "description"; 061 /** Parameter name for setting the version. Value is <tt>{@value}</tt>. */ 062 public static final String PARAM_VERSION = "version"; 063 /** Parameter name for setting the map. Value is <tt>{@value}</tt>. */ 064 public static final String PARAM_MAPPINGS = "map"; 065 /** Parameter name for setting the page. Value is <tt>{@value}</tt>. */ 066 public static final String PARAM_PAGE = "page"; 067 068 private static final String DEFAULT_DATEFORMAT = "dd-MMM-yyyy HH:mm:ss zzz"; 069 070 /** 071 * {@inheritDoc} 072 */ 073 public String execute( WikiContext context, Map<String, String> params ) 074 throws PluginException 075 { 076 String title; 077 String description; 078 String version; 079 String submitter = null; 080 SimpleDateFormat format = new SimpleDateFormat( DEFAULT_DATEFORMAT ); 081 ResourceBundle rb = Preferences.getBundle( context, WikiPlugin.CORE_PLUGINS_RESOURCEBUNDLE ); 082 083 title = params.get( PARAM_TITLE ); 084 description = params.get( PARAM_DESCRIPTION ); 085 version = params.get( PARAM_VERSION ); 086 087 Principal wup = context.getCurrentUser(); 088 089 if( wup != null ) 090 { 091 submitter = wup.getName(); 092 } 093 094 if( title == null ) throw new PluginException(rb.getString("bugreporthandler.titlerequired")); 095 if( title.length() == 0 ) return ""; 096 097 if( description == null ) description = ""; 098 if( version == null ) version = "unknown"; 099 100 Properties mappings = parseMappings( params.get( PARAM_MAPPINGS ) ); 101 102 // 103 // Start things 104 // 105 106 try 107 { 108 StringWriter str = new StringWriter(); 109 PrintWriter out = new PrintWriter( str ); 110 111 Date d = new Date(); 112 113 // 114 // Outputting of basic data 115 // 116 out.println("|"+mappings.getProperty(PARAM_TITLE,"Title")+"|"+title); 117 out.println("|"+mappings.getProperty("date","Date")+"|"+format.format(d)); 118 out.println("|"+mappings.getProperty(PARAM_VERSION,"Version")+"|"+version); 119 if( submitter != null ) 120 { 121 out.println("|"+mappings.getProperty("submitter","Submitter")+ 122 "|"+submitter); 123 } 124 125 // 126 // Outputting the other parameters added to this. 127 // 128 for( Iterator<Map.Entry<String, String>> i = params.entrySet().iterator(); i.hasNext(); ) 129 { 130 Map.Entry<String, String> entry = i.next(); 131 132 if( entry.getKey().equals( PARAM_TITLE ) || 133 entry.getKey().equals( PARAM_DESCRIPTION ) || 134 entry.getKey().equals( PARAM_VERSION ) || 135 entry.getKey().equals( PARAM_MAPPINGS ) || 136 entry.getKey().equals( PARAM_PAGE ) || 137 entry.getKey().startsWith("_") ) 138 { 139 // Ignore this 140 } 141 else 142 { 143 // 144 // If no mapping has been defined, just ignore 145 // it. 146 // 147 String head = mappings.getProperty( entry.getKey(), entry.getKey() ); 148 if( head.length() > 0 ) 149 { 150 out.println("|"+head+ 151 "|"+entry.getValue()); 152 } 153 } 154 } 155 156 out.println(); 157 out.println( description ); 158 159 out.close(); 160 161 // 162 // Now create a new page for this bug report 163 // 164 String pageName = findNextPage( context, title, params.get( PARAM_PAGE ) ); 165 166 WikiPage newPage = new WikiPage( context.getEngine(), pageName ); 167 WikiContext newContext = (WikiContext)context.clone(); 168 newContext.setPage( newPage ); 169 170 context.getEngine().saveText( newContext, 171 str.toString() ); 172 173 MessageFormat formatter = new MessageFormat(""); 174 formatter.applyPattern( rb.getString("bugreporthandler.new") ); 175 String[] args = { "<a href=\""+context.getViewURL(pageName)+"\">"+pageName+"</a>" }; 176 177 return formatter.format( args ); 178 } 179 catch( RedirectException e ) 180 { 181 log.info("Saving not allowed, reason: '"+e.getMessage()+"', can't redirect to "+e.getRedirect()); 182 183 throw new PluginException("Saving not allowed, reason: "+e.getMessage()); 184 } 185 catch( WikiException e ) 186 { 187 log.error("Unable to save page!",e); 188 189 return rb.getString("bugreporthandler.unable"); 190 } 191 } 192 193 /** 194 * Finds a free page name for adding the bug report. Tries to construct a page, 195 * and if it's found, adds a number to it and tries again. 196 */ 197 private synchronized String findNextPage( WikiContext context, 198 String title, 199 String baseName ) 200 { 201 String basicPageName = ((baseName != null)?baseName:"Bug")+MarkupParser.cleanLink(title); 202 203 WikiEngine engine = context.getEngine(); 204 205 String pageName = basicPageName; 206 long lastbug = 2; 207 208 while( engine.pageExists( pageName ) ) 209 { 210 pageName = basicPageName + lastbug++; 211 } 212 213 return pageName; 214 } 215 216 /** 217 * Just parses a mappings list in the form of "a=b;b=c;c=d". 218 * <p> 219 * FIXME: Should probably be in TextUtil or somewhere. 220 */ 221 private Properties parseMappings( String mappings ) 222 { 223 Properties props = new Properties(); 224 225 if( mappings == null ) return props; 226 227 StringTokenizer tok = new StringTokenizer( mappings, ";" ); 228 229 while( tok.hasMoreTokens() ) 230 { 231 String t = tok.nextToken(); 232 233 int colon = t.indexOf("="); 234 235 String key; 236 String value; 237 238 if( colon > 0 ) 239 { 240 key = t.substring(0,colon); 241 value = t.substring(colon+1); 242 } 243 else 244 { 245 key = t; 246 value = ""; 247 } 248 249 props.setProperty( key, value ); 250 } 251 252 return props; 253 } 254}