package org.gjt.bugrat.servlet;
import java.io.*;
import java.util.*;
import java.text.FieldPosition;
import java.text.SimpleDateFormat;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.mail.MessagingException;
import javax.mail.internet.InternetAddress;
import org.gjt.bugrat.db.*;
import org.gjt.bugrat.dbi.*;
public
class BugRatAdmin
extends BugRatServlet
{
public String
getServletInfo()
{
return "BugRat - Admin servlet, version "
+ this.getVersionStr() + " by Tim Endres.";
}
/**
* Override isAdmin() to return true, since we ARE da man!
*/
public boolean
isAdmin()
{
return true;
}
public void
init( ServletConfig config )
throws ServletException
{
super.init( config );
}
public void
doGet( HttpServletRequest req, HttpServletResponse res )
throws ServletException, IOException
{
BugRatRequest bReq = new BugRatRequest( req, res, this );
String pathInfo = bReq.getPathInfo();
if ( this.commonGet( bReq ) )
{
// Handled by the common GET code...
}
else if ( pathInfo == null || pathInfo.equals( "/" ) )
{
// UNDONE - Main Menu ?
this.sendIndexPage( bReq );
}
else if ( pathInfo.equalsIgnoreCase( "/index" ) ||
pathInfo.equalsIgnoreCase( "/index.html" ) )
{
this.sendIndexPage( bReq );
}
else if ( pathInfo.equalsIgnoreCase( "/MailQueueInfo" ) )
{
this.sendMailQueueInfoPage( bReq );
}
else if ( pathInfo.equalsIgnoreCase( "/ShowIdInfo" ) )
{
this.sendNextIdInfoPage( bReq );
}
else if ( pathInfo.equalsIgnoreCase( "/AdjustAllIds" ) )
{
this.adjustAllNextIds( bReq );
this.sendNextIdInfoPage( bReq );
}
else if ( pathInfo.startsWith( "/EditPrefs/" ) )
{
String prefSelector =
pathInfo.substring( "/EditPrefs/".length() );
this.sendEditPreferencesForm( bReq, prefSelector );
}
else if ( pathInfo.equalsIgnoreCase( "/LinkReport" ) )
{
this.chooseReportToLink( bReq );
}
else if ( pathInfo.startsWith( "/LinkReport/" ) )
{
int id = -1;
String idStr =
pathInfo.substring
( "/LinkReport/".length() );
try {
id = Integer.parseInt( idStr );
this.linkReport( bReq, id );
}
catch ( NumberFormatException ex )
{
PrintWriter cW = bReq.getHTMLWriter();
this.sendCommonHeader( bReq, cW, "BugRat Error" );
this.reportError
( bReq, cW,
"Could not parse Report ID '" +idStr+ "'" );
this.sendCommonTrailer( bReq, cW );
cW.close();
}
catch ( DBIException ex )
{
PrintWriter cW = bReq.getHTMLWriter();
this.sendCommonHeader( bReq, cW, "BugRat Error" );
this.reportError
( bReq, cW,
"Error linking Report ID '" +idStr+ "'" );
this.sendCommonTrailer( bReq, cW );
cW.close();
}
}
else if ( pathInfo.equalsIgnoreCase( "/EditBug" ) )
{
this.chooseBugToEdit( bReq );
}
else if ( pathInfo.startsWith( "/EditBug/" ) )
{
int id = -1;
String idStr =
pathInfo.substring
( "/EditBug/".length() );
try {
id = Integer.parseInt( idStr );
this.editBug( bReq, id );
}
catch ( NumberFormatException ex )
{
PrintWriter cW = bReq.getHTMLWriter();
this.sendCommonHeader( bReq, cW, "BugRat Error" );
this.reportError
( bReq, cW,
"Could not parse Bug ID '" + idStr + "'" );
this.sendCommonTrailer( bReq, cW );
cW.close();
}
}
else if ( pathInfo.startsWith( "/ReassignBug/" ) )
{
int id = -1;
String idStr =
pathInfo.substring
( "/ReassignBug/".length() );
try {
id = Integer.parseInt( idStr );
this.sendReassignForm( bReq, id, "Bug" );
}
catch ( NumberFormatException ex )
{
PrintWriter cW = bReq.getHTMLWriter();
this.sendCommonHeader( bReq, cW, "BugRat Error" );
this.reportError
( bReq, cW,
"Could not parse Bug ID '" + idStr + "'" );
this.sendCommonTrailer( bReq, cW );
cW.close();
}
}
else if ( pathInfo.startsWith( "/ReassignReport/" ) )
{
int id = -1;
String idStr =
pathInfo.substring
( "/ReassignReport/".length() );
try {
id = Integer.parseInt( idStr );
this.sendReassignForm( bReq, id, "Report" );
}
catch ( NumberFormatException ex )
{
PrintWriter cW = bReq.getHTMLWriter();
this.sendCommonHeader( bReq, cW, "BugRat Error" );
this.reportError
( bReq, cW,
"Could not parse Bug ID '" + idStr + "'" );
this.sendCommonTrailer( bReq, cW );
cW.close();
}
}
else if ( pathInfo.startsWith( "/CloseBug/" ) )
{
int id = -1;
String idStr =
pathInfo.substring( "/CloseBug/".length() );
try {
id = Integer.parseInt( idStr );
this.processClose( bReq, id, "Bug" );
}
catch ( NumberFormatException ex )
{
PrintWriter cW = bReq.getHTMLWriter();
this.sendCommonHeader( bReq, cW, "BugRat Error" );
this.reportError
( bReq, cW,
"Could not parse Bug ID '" + idStr + "'" );
this.sendCommonTrailer( bReq, cW );
cW.close();
}
}
else if ( pathInfo.startsWith( "/CloseReport/" ) )
{
int id = -1;
String idStr =
pathInfo.substring( "/CloseReport/".length() );
try {
id = Integer.parseInt( idStr );
this.processClose( bReq, id, "Report" );
}
catch ( NumberFormatException ex )
{
PrintWriter cW = bReq.getHTMLWriter();
this.sendCommonHeader( bReq, cW, "BugRat Error" );
this.reportError
( bReq, cW,
"Could not parse Report ID '" + idStr + "'" );
this.sendCommonTrailer( bReq, cW );
cW.close();
}
}
else if ( pathInfo.equalsIgnoreCase( "/EditProperty" ) )
{
this.sendPropertyListPage( bReq );
}
else if ( pathInfo.startsWith( "/EditProperty/" ) )
{
String propKey =
pathInfo.substring
( "/EditProperty/".length() );
this.sendEditPropertyForm( bReq, propKey );
}
else if ( pathInfo.equalsIgnoreCase( "/EditCategory" ) )
{
// this.sendEditCategoryPage( bReq, null );
}
else if ( pathInfo.startsWith( "/EditCategory/" ) )
{
String catStr =
pathInfo.substring
( "/EditCategory/".length() );
String[] catArgs = this.splitString( catStr , "/" );
this.sendEditCategoryPage( bReq, catArgs );
}
else
{
PrintWriter cW = bReq.getHTMLWriter();
this.sendCommonHeader( bReq, cW, "BugRat Error" );
this.reportError( bReq, cW,
"Servlet request (via pathinfo) not recognized." );
this.sendCommonTrailer( bReq, cW );
cW.close();
}
}
/**
* Write survey results to output file in response to the POSTed
* form. Write a "thank you" to the client.
*/
public void
doPost( HttpServletRequest req, HttpServletResponse res )
throws ServletException, IOException
{
BugRatRequest bReq = new BugRatRequest( req, res, this );
String pathInfo = bReq.getPathInfo();
if ( this.commonPost( bReq ) )
{
// Handled by the common GET code...
}
else if ( pathInfo == null )
{
// REVIEW
this.processShowReports( bReq );
}
else if ( pathInfo.equalsIgnoreCase( "/SetProperty" ) )
{
this.processSetProperty( bReq );
}
else if ( pathInfo.equalsIgnoreCase( "/SetCategory" ) )
{
this.processSetCategory( bReq );
}
else if ( pathInfo.equalsIgnoreCase( "/ReassignBug" ) )
{
this.processReassign( bReq, "Bug" );
}
else if ( pathInfo.equalsIgnoreCase( "/ReassignReport" ) )
{
this.processReassign( bReq, "Report" );
}
else if ( pathInfo.equalsIgnoreCase( "/LinkReportPost" ) )
{
this.processLinkReportPost( bReq );
}
else if ( pathInfo.equalsIgnoreCase( "/PostEditBug" ) )
{
this.processEditBug( bReq );
}
else if ( pathInfo.equalsIgnoreCase( "/SavePrefs" ) )
{
this.processSavePrefs( bReq );
}
else
{
PrintWriter cW = bReq.getHTMLWriter();
this.sendCommonHeader
( bReq, cW, "BugRat - Error Unknown Command" );
this.reportError( bReq, cW,
"Servlet request (via pathinfo) not recognized." );
this.sendCommonTrailer( bReq, cW );
cW.close();
}
}
private void
sendReassignForm( BugRatRequest bReq, int id, String target )
throws IOException
{
PrintWriter cW = bReq.getHTMLWriter();
this.sendCommonHeader
( bReq, cW, "BugRat - Reassign " + target + " # '" + id + "'" );
cW.println( "<H2>Reassign " + target + " # '" + id + "'</H2>" );
cW.println( "Use this form to assign a " + target + " to another person." );
try {
Object item =
target.equalsIgnoreCase( "bug" )
? (Object) Bug.getBug( id )
: (Object) Report.getReport( id );
if ( item == null )
throw new DBIException
( target + " ID=" + id + " does not exist" );
int respId =
target.equalsIgnoreCase( "bug" )
? ((Bug) item).getResponsible()
: ((Report) item).getResponsible();
Person p = Person.getPerson( respId );
cW.print ( "<FORM method=\"POST\" action=\"" );
cW.print ( bReq.getServletPath() );
cW.print ( "/Reassign" );
cW.print ( target );
cW.print ( "\">" );
cW.print ( "<INPUT type=\"hidden\"" );
cW.println( " name=\"id\" value=\"" + id + "\">" );
cW.println( "Reassign the " + target + " with ID " );
cW.println( id );
cW.println( " <strong>from</strong> " );
cW.println( (p == null) ? "Not assigned" : p.getName() );
if ( p != null )
{
cW.println( " ( " );
cW.println( p.getEmail() );
cW.println( " )" );
}
cW.println( "<strong>to:</strong>" );
cW.println( "<P>" );
this.getOutput().sendPersonSelector
( bReq, cW, -1,
( (p == null) ? -1 : p.getId() ),
"responsible", null, null );
cW.println( "<P>" );
cW.print ( "<INPUT type=\"submit\"" );
cW.println( " name=\"submit\" value=\"Reassign\">" );
cW.println( "</FORM>" );
}
catch ( DBIException ex )
{
cW.println( "<hr>" );
this.getOutput().reportError( bReq, cW,
"Error getting " + target + " #" + id
+ " to reassign, " + ex.getMessage() );
}
this.sendCommonTrailer( bReq, cW );
cW.close();
}
/**
*
* processReassignBug - reassign a bug to another person
*
* UNDONE This is not thread safe due to the ability for one
* servlet to define the action, then another to modify
* the assignment, then the first commits, leaving the
* audit trail out of sync.
*
* We need to create locks for bugs and reports.
*
*/
private void
processReassign( BugRatRequest bReq, String target )
throws IOException
{
DBConfig config = this.getDBConfig();
PrintWriter cW = bReq.getHTMLWriter();
this.sendCommonHeader
( bReq, cW, "BugRat - Reassign " + target );
boolean isBug = target.equalsIgnoreCase( "Bug" );
try {
String value;
String[] valAry;
valAry = bReq.getParameterValues( "id" );
if ( this.isEmptyParameter( valAry ) )
throw this.new RequiredException( "id" );
String idStr = valAry[0];
valAry = bReq.getParameterValues( "responsible" );
if ( this.isEmptyParameter( valAry ) )
throw this.new RequiredException( "responsible" );
String personIdStr = valAry[0];
int id = -1;
int personId = -1;
try {
id = Integer.parseInt( idStr );
personId = Integer.parseInt( personIdStr );
Object item = isBug
? (Object) Bug.getBug( id )
: (Object) Report.getReport( id );
if ( item == null )
{
cW.println( "<h2>Reassigning " +target+ " #" + id + "</h2>" );
this.reportError( bReq, cW,
"Could not retrieve " +target+ " #" + id );
}
else
{
int oldRespId = 0;
if ( isBug )
{
Bug bug = (Bug) item;
oldRespId = bug.getResponsible();
bug.setResponsible( personId );
bug.commit();
}
else
{
Report rep = (Report) item;
oldRespId = rep.getResponsible();
rep.setResponsible( personId );
rep.commit();
}
BugRatAction action =
BugRatAction.getNewAction( ACTION_ASSIGN );
int actorId = this.getUserId( bReq );
if ( actorId == 0 )
{
this.log
( "WARNING getUserId() returned no actor "
+ "for action #" + action.getId() );
}
action.setActorId( actorId );
action.setActionTime( new Date() );
action.setTarget( isBug ? TARGET_BUG : TARGET_REPORT );
action.setTargetId( id );
action.setArgOne( oldRespId );
action.setArgTwo( personId );
action.setComment
( "assigned "
+ (isBug ? "bug" : "report" )
+ " #" + id
+ " from person #" + oldRespId
+ " to person #" + personId
+ " by person #" + actorId );
action.commit();
String address = null;
Person p = Person.getPerson( personId );
if ( p == null )
{
throw new DBIException
( "Could not find assignment person #"
+ personId );
}
Person oldP = Person.getPerson( oldRespId );
String subject =
"BugRat " +target+ " #" + id
+ " was assigned to " + p.getName();
StringBuffer body = new StringBuffer();
body.append( target + " #" );
body.append( id );
body.append( " was assigned to Person #" );
body.append( personId );
body.append( "\n\n" );
body.append( " Name: " );
body.append( p.getName() );
body.append( "\n" );
body.append( " Email: " );
body.append( p.getEmail() );
body.append( "\n" );
body.append( " HomePage: " );
body.append( p.getURL() );
body.append( "\n" );
body.append( " Phone: " );
body.append( p.getPhone() );
body.append( "\n" );
body.append( " FAX: " );
body.append( p.getFAX() );
body.append( "\n\n" );
if ( oldP != null )
{
body.append( "The " );
body.append( isBug ? "bug" : "report" );
body.append( " was previously assigned to person #" );
body.append( oldP.getId() );
body.append( "\n\n" );
body.append( " Name: " );
body.append( oldP.getName() );
body.append( "\n" );
body.append( " Email: " );
body.append( oldP.getEmail() );
body.append( "\n" );
body.append( " HomePage: " );
body.append( oldP.getURL() );
body.append( "\n" );
body.append( " Phone: " );
body.append( oldP.getPhone() );
body.append( "\n" );
body.append( " FAX: " );
body.append( oldP.getFAX() );
}
else
{
body.append( "The " );
body.append( isBug ? "bug" : "report" );
body.append( " was previously unassigned." );
}
InternetAddress[] toAddrs =
new InternetAddress[ (oldP == null) ? 1 : 2 ];
toAddrs[0] =
new InternetAddress
( p.getEmail(), p.getName() );
if ( oldP != null )
{
toAddrs[1] =
new InternetAddress
( oldP.getEmail(), oldP.getName() );
}
this.mailQueue.addMailJob
( subject, body.toString(), toAddrs, null );
if ( isBug )
this.getOutput().showBug( bReq, cW, id );
else
this.getOutput().showReport( bReq, cW, id );
}
}
catch ( NumberFormatException ex )
{
cW.println( "<h2>Reassigning " + target + "</h2>" );
throw this.new RequiredException
( "could not parse '"
+ ( (id == -1)
? ( isBug ? "bug" : "report" )
: "person" )
+ "' id, " + ex.getMessage() );
}
catch ( DBIException ex )
{
cW.println( "<h2>Reassigning " + target + "</h2>" );
this.reportError( bReq, cW,
"Error committing reassignment of "
+ target + " #" + id + ", " + ex.getMessage() );
}
}
catch ( RequiredException ex )
{
cW.println( "<h2>Required Field Missing</h2>" );
this.reportError( bReq, cW,
"The required field '" + ex.getMessage() + "' is missing!" );
}
this.sendCommonTrailer( bReq, cW );
cW.close();
}
/**
*
* processClose - close a bug or a report
*
*/
private void
processClose( BugRatRequest bReq, int id, String target )
throws IOException
{
DBConfig config = this.getDBConfig();
PrintWriter cW = bReq.getHTMLWriter();
this.sendCommonHeader
( bReq, cW, "BugRat - Closed " + target );
boolean isBug = target.equalsIgnoreCase( "Bug" );
try {
Object item =
isBug
? (Object) Bug.getBug( id )
: (Object) Report.getReport( id );
if ( item == null )
{
cW.println( "<h2>Closing " +target+ " #" + id + "</h2>" );
this.reportError( bReq, cW,
"Could not retrieve " + target + " #" + id );
}
else
{
int respId = 0;
if ( isBug )
{
Bug bug = (Bug) item;
bug.setState( STATE_CLOSED );
bug.setCloseDate( new Date() );
bug.commit();
respId = bug.getResponsible();
}
else
{
Report rep = (Report) item;
rep.setState( STATE_CLOSED );
// Reports don't have close dates....
// rep.setCloseDate( new Date() );
rep.commit();
respId = rep.getResponsible();
}
BugRatAction action =
BugRatAction.getNewAction( ACTION_CLOSE );
int actorId = this.getUserId( bReq );
if ( actorId == 0 )
{
this.log
( "WARNING getUserId() returned no actor "
+ "for action #" + action.getId() );
}
action.setActorId( actorId );
action.setActionTime( new Date() );
action.setTarget( isBug ? TARGET_BUG : TARGET_REPORT );
action.setTargetId( id );
action.setArgOne( 0 );
action.setArgTwo( 0 );
action.setComment
( "closed " + (isBug?"bug":"report") + " #" + id );
action.commit();
String address = null;
String subject =
"BugRat " +target+ " #" + id
+ " was closed";
StringBuffer body = new StringBuffer();
body.append( target );
body.append( " #" );
body.append( id );
body.append( " was closed by Person #" );
Description desc = isBug
? ((Bug) item).getDescription()
: ((Report) item).getDescription();
if ( desc != null )
{
body.append( actorId );
body.append( "\n\n" );
body.append( " Synopsis: " );
body.append( desc.getSynopsis() );
// UNDONE - Add the description? All details?
// We need some common "formatters"
// to produce text/plain and text/html
// descriptions of bugs and reports.
}
// If this is a bug, send notice to submitters of
// all reports linked to this bug.
Vector repV = null;
if ( isBug )
{
repV = Report.matchReports
(
"SELECT report.id " +
"FROM report, repbug " +
"WHERE report.id = repbug.report " +
"AND repbug.bug = " + id
);
}
else
{
repV = new Vector();
repV.addElement( (Report) item );
}
Person p = Person.getPerson( respId );
if ( p == null )
{
respId = config.getDefaultResponsible();
p = Person.getPerson( respId );
}
if ( p != null )
{
InternetAddress[] toAddrs =
new InternetAddress[ 1 ];
toAddrs[0] =
new InternetAddress
( p.getEmail(), p.getName() );
InternetAddress[] ccAddrs = null;
if ( repV.size() > 0 )
{
Vector ccV = new Vector();
for ( int i = 0, sz = repV.size(); i < sz ; i ++ )
{
Report rep = (Report) repV.elementAt( i );
Person sub =
Person.getPerson( rep.getSubmitter() );
if ( sub != null )
{
ccV.addElement
( new InternetAddress
( sub.getEmail(), sub.getName() ) );
}
}
ccAddrs = new InternetAddress[ ccV.size() ];
ccV.copyInto( ccAddrs );
}
this.mailQueue.addMailJob
( subject, body.toString(), toAddrs, ccAddrs );
}
else
{
// UNDONE Log case of no resposible person, or
}
if ( isBug )
this.getOutput().showBug( bReq, cW, id );
else
this.getOutput().showReport( bReq, cW, id );
}
}
catch ( DBIException ex )
{
cW.println( "<h2>Closing " +target+ "</h2>" );
this.reportError( bReq, cW,
"Error committing closure of "
+ (isBug?"bug":"report") + " #"
+ id + ", " + ex.getMessage() );
}
this.sendCommonTrailer( bReq, cW );
cW.close();
}
private void
sendEditPropertyForm( BugRatRequest bReq, String propKey )
throws IOException
{
PrintWriter cW = bReq.getHTMLWriter();
this.sendCommonHeader
( bReq, cW, "BugRat - Edit Property '" + propKey + "'" );
String propValue = "";
BRATProperty prop = null;
if ( propKey != null && propKey.length() > 0 )
{
try { prop = BRATProperty.getProperty( propKey ); }
catch ( DBIException ex )
{ prop = null; }
}
cW.println( "<h2>Edit Property " );
cW.println( (propKey==null || propKey.length()==0) ? "" : propKey );
cW.println( "</h2>" );
cW.println( "Use this form to add or edit properties." );
if ( prop == null )
{
cW.println( "<p>" );
cW.println( "<B>NOTE</B>" );
cW.println( "The property named '" );
cW.println( propKey );
cW.println( "' was not found in the property table in the" );
cW.println( "database. If you set the property via this form" );
cW.println( "a new entry will be created in the property" );
cW.println( "table with the key and value you enter." );
}
else
{
propValue = prop.getValue();
}
cW.print ( "<FORM method=\"POST\" action=\"" );
cW.print ( bReq.getServletPath() );
cW.print ( "/SetProperty\">" );
cW.println( "<strong>Property Key:</strong>" );
cW.print ( "<INPUT type=\"textfield\" size=\"48\"" );
cW.print ( " name=\"propkey\" value=\"" );
cW.print ( propKey );
cW.println( "\">" );
cW.println( "<br>" );
cW.println( "<strong>Property Value:</strong>" );
cW.println( "<br>" );
cW.println( "<textarea rows=24 cols=64 name=\"propvalue\">" );
cW.println( propValue );
cW.println( "</textarea>" );
cW.println( "<br>" );
cW.print ( "<INPUT type=\"submit\"" );
cW.print ( " name=\"submit\" value=\"Set Property\">" );
cW.println( "</FORM>" );
this.sendCommonTrailer( bReq, cW );
cW.close();
}
private void
sendPropertyListPage( BugRatRequest bReq )
throws IOException
{
PrintWriter cW = bReq.getHTMLWriter();
this.sendCommonHeader
( bReq, cW, "BugRat - Config Properties" );
cW.println( "<h2>BugRat Configuration Properties</h2>" );
cW.println( "Click on any property to view/edit its value." );
cW.println( "<UL>" );
Vector sKeys = new Vector( 256 );
Enumeration enum = this.dbConfig.getPropertyEnumerator();
for ( ; enum.hasMoreElements() ; )
{
boolean inserted = false;
BRATProperty prop = (BRATProperty) enum.nextElement();
String key = prop.getKey().toLowerCase();
for ( int i = 0, sz = sKeys.size() ; i < sz ; ++i )
{
String vKey = ((String)sKeys.elementAt(i)).toLowerCase();
if ( key.compareTo( vKey ) < 0 )
{
inserted = true;
sKeys.insertElementAt( prop.getKey(), i );
break;
}
}
if ( ! inserted )
{
sKeys.addElement( prop.getKey() );
}
}
for ( int i = 0, sz = sKeys.size() ; i < sz ; ++i )
{
String key = (String) sKeys.elementAt(i);
cW.println( "<LI>" );
cW.print ( "<A HREF=\"" );
cW.print ( bReq.getServletPath() );
cW.print ( "/EditProperty/" );
cW.print ( key );
cW.println( "\">" );
cW.println( "<strong>" );
cW.println( key );
cW.println( "</strong>" );
cW.println( "</A>" );
cW.println( "</LI>" );
}
cW.println( "</UL>" );
this.sendCommonTrailer( bReq, cW );
cW.close();
}
/**
*
* processSetProperty - process the posting of an edited bug
*
*
*/
private void
processSetProperty( BugRatRequest bReq )
throws IOException
{
DBConfig config = this.getDBConfig();
PrintWriter cW = bReq.getHTMLWriter();
this.sendCommonHeader
( bReq, cW, "BugRat - Edit Property" );
cW.println( "<h2>Setting Property</h2>" );
try {
String value;
String[] valAry;
valAry = bReq.getParameterValues( "propkey" );
if ( this.isEmptyParameter( valAry ) )
throw this.new RequiredException( "propkey" );
String propKey = valAry[0];
valAry = bReq.getParameterValues( "propvalue" );
if ( this.isEmptyParameter( valAry ) )
throw this.new RequiredException( "propvalue" );
String propValue = valAry[0];
try {
BRATProperty prop =
BRATProperty.getProperty( propKey );
if ( prop == null )
{
prop = new BRATProperty( propKey, propValue );
}
else
{
prop.setValue( propValue );
}
prop.commit();
this.getDBConfig().retrieveConfiguration();
cW.print ( "Successfully set property <strong>'" );
cW.print ( prop.getKey() );
cW.println( "'</strong>." );
cW.println( "<h3>Value:</h3>" );
cW.print ( "<pre>" );
cW.print ( prop.getValue() );
cW.println( "</pre>" );
}
catch ( DBIException ex )
{
this.reportError( bReq, cW,
"Error committing property '" + propKey + "' to database, "
+ ex.getMessage() );
}
}
catch ( RequiredException ex )
{
this.reportError( bReq, cW,
"Required field '" + ex.getMessage() + "' is missing!" );
}
this.sendCommonTrailer( bReq, cW );
cW.close();
}
private void
sendEditCategoryPage( BugRatRequest bReq, String[] catArgs )
throws IOException
{
PrintWriter cW = bReq.getHTMLWriter();
cW.println( "<h2>Edit Category</h2>" );
cW.println( "Use this form to change the person responsible for " );
cW.println( "this category, or to change its display name or its " );
cW.println( "description. You can not change the pkg, category, or " );
cW.println( "subcat, since they are primaty keys. You must create a " );
cW.println( "new record and delete the old one to change one of the " );
cW.println( "key values." );
this.sendEditCategoryForm( bReq, cW, catArgs );
this.sendCommonTrailer( bReq, cW );
cW.close();
}
private void
sendEditCategoryForm( BugRatRequest bReq, PrintWriter cW, String[] catArgs )
throws IOException
{
DBConfig config = this.getDBConfig();
String pkgStr = catArgs[0];
String catStr = (catArgs.length > 1) ? catArgs[1] : "";
String subStr = (catArgs.length > 2) ? catArgs[2] : "";
String displayName = pkgStr + "," + catStr + "," + subStr;
Category cat = null;
try { cat = Category.getCategory( pkgStr, catStr, subStr ); }
catch ( DBIException ex )
{ cat = null; }
if ( cat == null )
{
this.reportError( bReq, cW,
"Category '" + displayName + "' does not exist." );
}
else
{
cW.print ( "<FORM method=\"POST\" action=\"" );
cW.print ( bReq.getServletPath() );
cW.print ( "/SetCategory\">" );
cW.print ( "<INPUT type=\"hidden\" name=\"pkg\"" );
cW.print ( " value=\"" + pkgStr + "\">" );
cW.print ( "<INPUT type=\"hidden\" name=\"cat\"" );
cW.print ( " value=\"" + catStr + "\">" );
cW.print ( "<INPUT type=\"hidden\" name=\"sub\"" );
cW.print ( " value=\"" + subStr + "\">" );
cW.println( "<table width=\"100%\">" );
cW.println( "<tr>" );
cW.println( "<th align=\"left\">" );
cW.println( "Project:" );
cW.println( "</th>" );
boolean linkIt;
linkIt = cat.isCategory() || cat.isSubCategory();
cW.println( "<td>" );
if ( linkIt )
{
cW.println( "<A HREF=\"" );
cW.print ( bReq.getServletPath() );
cW.print ( "/EditCategory/" );
cW.print ( pkgStr );
cW.println( "\">" );
}
cW.println( config.getProjectName( pkgStr ) );
if ( linkIt )
{
cW.println( "</A>" );
}
cW.print ( "( " );
cW.print ( cat.getProject() );
cW.println( " )" );
cW.println( "</td>" );
cW.println( "</tr>" );
if ( cat.isCategory()
|| cat.isSubCategory() )
{
cW.println( "<tr>" );
cW.println( "<th align=\"left\">" );
cW.println( "Category:" );
cW.println( "</th>" );
linkIt = cat.isSubCategory();
cW.println( "<td>" );
if ( linkIt )
{
cW.println( "<A HREF=\"" );
cW.print ( bReq.getServletPath() );
cW.print ( "/EditCategory/" );
cW.print ( pkgStr );
cW.print ( "/" );
cW.print ( catStr );
cW.println( "\">" );
}
cW.println( config.getCategoryName( pkgStr, catStr ) );
if ( linkIt )
{
cW.println( "</A>" );
}
cW.print ( "( " );
cW.print ( cat.getCategory() );
cW.println( " )" );
cW.println( "</td>" );
cW.println( "</tr>" );
}
if ( cat.isSubCategory() )
{
cW.println( "<tr>" );
cW.println( "<th align=\"left\">" );
cW.println( "SubCategory:" );
cW.println( "</th>" );
cW.println( "<td>" );
cW.println( config.getSubCategoryName
( pkgStr, catStr, subStr ) );
cW.print ( "( " );
cW.print ( cat.getSubCategory() );
cW.println( " )" );
cW.println( "</td>" );
cW.println( "</tr>" );
}
cW.println( "<tr>" );
cW.println( "<th align=\"left\">" );
cW.println( "Responsible:" );
cW.println( "</th>" );
cW.println( "<td>" );
String notAssigned =
"<OPTION VALUE=\"0\"> Not Assigned </OPTION>";
Person p = null;
try { p = Person.getPerson( cat.getResponsible() ); }
catch ( DBIException ex )
{ p = null; }
this.getOutput().sendPersonSelector
( bReq, cW,
( (p == null) ? -1 : p.getId() ), -1,
"responsible", notAssigned, null );
cW.println( "</td>" );
cW.println( "</tr>" );
cW.println( "<tr>" );
cW.println( "<th align=\"left\">" );
cW.println( "Name:" );
cW.println( "</th>" );
cW.println( "<td>" );
cW.print ( "<INPUT type=\"textfield\" size=\"48\"" );
cW.print ( " name=\"catname\" value=\"" );
cW.print ( cat.getName() );
cW.println( "\">" );
cW.println( "</td>" );
cW.println( "</tr>" );
cW.println( "<tr>" );
cW.println( "<th align=\"left\" valign=\"top\">" );
cW.println( "Description:" );
cW.println( "</th>" );
cW.println( "<td>" );
cW.println( "<textarea rows=6 cols=48 name=\"catdesc\">" );
cW.println( cat.getDescription() );
cW.println( "</textarea>" );
cW.println( "</td>" );
cW.println( "</tr>" );
cW.println( "<tr>" );
cW.println( "<td colspan=\"2\" align=\"center\">" );
cW.print ( "<INPUT type=\"submit\"" );
cW.print ( " name=\"submit\" value=\"Save Category\">" );
cW.println( "</td>" );
cW.println( "</tr>" );
cW.println( "</table>" );
cW.println( "</FORM>" );
}
}
/**
*
* processSetProperty - process the posting of an edited bug
*
*
*/
private void
processSetCategory( BugRatRequest bReq )
throws IOException
{
DBConfig config = this.getDBConfig();
PrintWriter cW = bReq.getHTMLWriter();
this.sendCommonHeader
( bReq, cW, "BugRat - Saving Category" );
try {
String[] valAry;
String pkgStr, catStr, subStr;
valAry = bReq.getParameterValues( "pkg" );
if ( this.isEmptyParameter( valAry ) )
throw this.new RequiredException( "project id" );
pkgStr = valAry[0];
valAry = bReq.getParameterValues( "cat" );
if ( this.isEmptyParameter( valAry ) )
catStr = "";
else
catStr = valAry[0];
valAry = bReq.getParameterValues( "sub" );
if ( this.isEmptyParameter( valAry ) )
subStr = "";
else
subStr = valAry[0];
valAry = bReq.getParameterValues( "catname" );
if ( this.isEmptyParameter( valAry ) )
throw this.new RequiredException( "category name" );
String catName = valAry[0];
valAry = bReq.getParameterValues( "responsible" );
if ( this.isEmptyParameter( valAry ) )
throw this.new RequiredException( "person responsible" );
String respStr = valAry[0];
valAry = bReq.getParameterValues( "catdesc" );
if ( this.isEmptyParameter( valAry ) )
throw this.new RequiredException( "category description" );
String catDesc = valAry[0];
try {
Category cat =
Category.getCategory( pkgStr, catStr, subStr );
if ( cat == null )
{
this.reportError( bReq, cW,
"Could not locate category '"
+ pkgStr + "," + catStr + "," + subStr
+ "'." );
}
else
{
int respId = Integer.parseInt( respStr );
cat.setName( catName );
cat.setResponsible( respId );
cat.setDescription( catDesc );
}
cat.commit();
config.retrieveCategories();
int alen =
( subStr.length() > 0 ? 3 :
( catStr.length() > 0 ? 2 : 1 ) );
String[] catArgs = new String[ alen ];
catArgs[0] = pkgStr;
if ( catArgs.length > 1 )
catArgs[1] = catStr;
if ( catArgs.length > 2 )
catArgs[2] = subStr;
cW.println( "<h2>Category Saved</h2>" );
cW.println( "Your modifications to the category were saved. " );
cW.println( "You may continue to edit the category with this " );
cW.println( "form. " );
this.sendEditCategoryForm( bReq, cW, catArgs );
}
catch ( DBIException ex )
{
cW.println( "<h2>Error Saving Category</h2>" );
this.reportError( bReq, cW,
"Error committing category '"
+ pkgStr + "," + catStr + "," + subStr
+ "', " + ex.getMessage() );
}
catch ( NumberFormatException ex )
{
cW.println( "<h2>Error Saving Category</h2>" );
this.reportError( bReq, cW,
"Error parsing category person responsible id '"
+ respStr + "', " + ex.getMessage() );
}
}
catch ( RequiredException ex )
{
cW.println( "<h2>Error Saving Category</h2>" );
this.reportError( bReq, cW,
"Required field '" + ex.getMessage() + "' is missing!" );
}
this.sendCommonTrailer( bReq, cW );
cW.close();
}
private void
chooseReportToLink( BugRatRequest bReq )
throws IOException
{
PrintWriter cW = bReq.getHTMLWriter();
this.sendCommonHeader( bReq, cW, "BugRat - Link Report To Bug" );
cW.println( "<h2>Select A Project</h2>" );
cW.println( "Use this form to show all of the reports in the." );
cW.println( "project that you specify. Select the project you" );
cW.println( "are interested in from the list below, and click" );
cW.println( "the 'Show Reports' button to see the list of reports." );
cW.println( "<FORM method=\"POST\" action=\"ShowReports\">" );
cW.println( "Project:<br>" );
cW.print ( "<INPUT type=\"hidden\"" );
cW.println( " name=\"scope\" value=\"project\">" );
cW.print ( "<INPUT type=\"hidden\"" );
cW.println( " name=\"action\" value=\"LinkReport\">" );
cW.println( "<SELECT name=\"project\" size=\"10\">" );
Vector projects = this.getDBConfig().getProjects();
for ( int i = 0, sz = projects.size() ; i < sz ; ++i )
{
Category pc = (Category) projects.elementAt(i);
String projStr = pc.getProject();
String projectName = pc.getName();
cW.print ( "<OPTION value=\"" + projStr + "\">" );
cW.println( projectName );
}
cW.println( "</SELECT>" );
cW.println( "<br>" );
cW.print ( "<INPUT type=\"submit\"" );
cW.println( " name=\"submit\" value=\"Show Reports\">" );
cW.println( "</FORM>" );
this.sendCommonTrailer( bReq, cW );
cW.close();
}
private void
chooseBugToEdit( BugRatRequest bReq )
throws IOException
{
PrintWriter cW = bReq.getHTMLWriter();
this.sendCommonHeader( bReq, cW, "BugRat - Edit Bug" );
cW.println( "<h2>Select A Project</h2>" );
cW.println( "Use this form to show all of the bugs in the." );
cW.println( "project that you specify. Select the project you" );
cW.println( "are interested in from the list below, and click" );
cW.println( "the 'Show Bugs' button to see the list of bugs." );
cW.println( "<FORM method=\"POST\" action=\"ShowBugs\">" );
cW.println( "Project:<br>" );
cW.print ( "<INPUT type=\"hidden\"" );
cW.println( " name=\"scope\" value=\"project\">" );
cW.print ( "<INPUT type=\"hidden\"" );
cW.println( " name=\"action\" value=\"EditBug\">" );
cW.println( "<SELECT name=\"project\" size=\"10\">" );
Vector projects = this.getDBConfig().getProjects();
for ( int i = 0, sz = projects.size() ; i < sz ; ++i )
{
Category pc = (Category) projects.elementAt(i);
String projStr = pc.getProject();
String projectName = pc.getName();
cW.print ( "<OPTION value=\"" + projStr + "\">" );
cW.println( projectName );
}
cW.println( "</SELECT>" );
cW.println( "<br>" );
cW.print ( "<INPUT type=\"submit\"" );
cW.println( " name=\"submit\" value=\"Show Bugs\">" );
cW.println( "</FORM>" );
this.sendCommonTrailer( bReq, cW );
cW.close();
}
private void
sendIndexPage( BugRatRequest bReq )
throws IOException
{
PrintWriter cW = bReq.getHTMLWriter();
this.sendCommonHeader( bReq, cW, "BugRat - Admin Servlet" );
this.sendPropertyHTML( bReq, cW, "adminServlet.indexHtml" );
this.sendCommonTrailer( bReq, cW );
cW.close();
}
private void
sendEditPreferencesForm( BugRatRequest bReq, String prefSelector )
throws IOException
{
PrintWriter cW = bReq.getHTMLWriter();
this.sendCommonHeader( bReq, cW, "BugRat - Edit Bug" );
if ( prefSelector.equalsIgnoreCase( "Admin" ) )
{
this.sendAdminPrefsForm( bReq, cW );
}
else
{
cW.println( "<h2>UNKNOWN Preferences</h2>" );
cW.print ( "THIS IS AN INTERNAL ERROR. Selector = '" );
cW.print ( prefSelector );
cW.println( "'." );
}
this.sendCommonTrailer( bReq, cW );
cW.close();
}
private void
sendAdminPrefsForm( BugRatRequest bReq, PrintWriter cW )
throws IOException
{
boolean allowBugComments =
bReq.allowsBugComments();
boolean newUserRequiresAdmin =
bReq.getNewUserRequiresAdmin();
cW.println( "<h2>Administrative Preferences</h2>" );
cW.println( "Use this form to edit the administration preferences." );
cW.println( "<FORM method=\"POST\" action=\"" );
cW.println( bReq.getServletPath() );
cW.println( "/SavePrefs\">" );
cW.print ( "<INPUT type=\"hidden\"" );
cW.println( " name=\"scope\" value=\"admin\">" );
cW.print ( "<INPUT type=\"checkbox\" name=\"newuserpublic\"" );
if ( ! newUserRequiresAdmin )
cW.print( " checked " );
cW.print ( " value=\"true\">" );
cW.println( " New User May Be Created By Anyone" );
cW.println( "<p>" );
cW.print ( "<INPUT type=\"checkbox\" name=\"bugcomments\"" );
if ( allowBugComments )
cW.print( " checked " );
cW.print ( " value=\"true\">" );
cW.println( " Allow admin to add comments to bugs" );
cW.println( "<p>" );
cW.print ( "<INPUT type=\"submit\"" );
cW.println( " name=\"submit\" value=\"Save Preferences\">" );
cW.println( "</FORM>" );
}
private void
processSavePrefs( BugRatRequest bReq )
throws IOException
{
DBConfig config = this.getDBConfig();
PrintWriter cW = bReq.getHTMLWriter();
this.sendCommonHeader
( bReq, cW, "BugRat - Save Preferences" );
try {
String[] valAry = bReq.getParameterValues( "scope" );
if ( this.isEmptyParameter( valAry ) )
throw this.new RequiredException( "scope" );
String scopeStr = valAry[0];
String key = null;
String value = null;
BRATProperty prop = null;
if ( scopeStr.equalsIgnoreCase( "admin" ) )
{
boolean newUserPublic = false;
valAry = bReq.getParameterValues( "newuserpublic" );
if ( this.isEmptyParameter( valAry ) )
newUserPublic = false;
else
newUserPublic = true;
boolean bugComments = false;
valAry = bReq.getParameterValues( "bugcomments" );
if ( this.isEmptyParameter( valAry ) )
bugComments = false;
else
bugComments = true;
try {
key = "commonServlet.allowsBugComments";
value = bugComments ? "true" : "false";
prop = BRATProperty.getProperty( key );
if ( prop != null )
prop.setValue( value );
else
prop = new BRATProperty( key, value );
prop.commit();
key = "commonServlet.newPersonRequiresAdmin";
value = newUserPublic ? "false" : "true";
prop = BRATProperty.getProperty( key );
if ( prop != null )
prop.setValue( value );
else
prop = new BRATProperty( key, value );
prop.commit();
this.getDBConfig().retrieveConfiguration();
this.sendAdminPrefsForm( bReq, cW );
}
catch ( DBIException ex )
{
cW.println( "<h2>Error Saving Preferences</h2>" );
this.reportError( bReq, cW,
"Error saving preferences to database, key='"
+ key + "', " + ex.getMessage() );
}
}
else
{
cW.println( "<h2>Error Saving Preferences</h2>" );
this.reportError( bReq, cW,
"Error saving preferences to database, "
+ "unknown scope '" + scopeStr + "'" );
}
}
catch ( RequiredException ex )
{
this.reportError( bReq, cW,
"Required field '" + ex.getMessage() + "' is missing" );
}
this.sendCommonTrailer( bReq, cW );
cW.close();
}
private void
sendMailQueueInfoPage( BugRatRequest bReq )
throws IOException
{
PrintWriter cW = bReq.getHTMLWriter();
this.sendCommonHeader( bReq, cW, "BugRat - Admin Servlet" );
cW.println( "<h2>Admin Mail Queue Information</h2>" );
if ( this.mailQueue == null )
{
cW.println( "The mail queue has not been established yet.<br>" );
cW.println( "Try refreshing this page in a few seconds." );
}
else
{
StringBuffer buf = new StringBuffer();
this.dateFmt.format
( this.mailQueue.getStartTime(), buf, new FieldPosition(0) );
cW.println( "<p>" );
cW.println( "<B>Start Time:</B> " );
cW.println( buf.toString() );
cW.println( "</p>" );
buf.setLength(0);
Date last = this.mailQueue.getLastMailTime();
if ( last != null )
this.dateFmt.format( last, buf, new FieldPosition(0) );
else
buf.append( "No email has been successfully sent yet." );
cW.println( "<p>" );
cW.println( "<B>Mail Transport:</B> " );
cW.println( this.mailQueue.getTransportName() );
cW.println( "</p>" );
cW.println( "<p>" );
cW.println( "<B>Mail Hostname:</B> " );
cW.println( this.mailQueue.getMailHostname() );
cW.println( "</p>" );
cW.println( "<p>" );
cW.println( "<B>Administrator Address:</B> " );
cW.println( this.mailQueue.getAdminAddress() );
cW.println( "</p>" );
cW.println( "<p>" );
cW.println( "<B>Last Mail Time:</B> " );
cW.println( buf.toString() );
cW.println( "</p>" );
cW.println( "<p>" );
cW.println( "<B>Number Of Messages Mailed:</B> " );
cW.println( "" + this.mailQueue.getNumMessagesMailed() );
cW.println( "</p>" );
cW.println( "<p>" );
cW.println( "<B>Number Of Messages Failed:</B> " );
cW.println( "" + this.mailQueue.getNumMessagesFailed() );
cW.println( "</p>" );
cW.println( "<p>" );
cW.println( "<B>Current Number of Messages Queued:</B> " );
cW.println( "" + this.mailQueue.getQueueSize() );
cW.println( "</p>" );
Enumeration enum = this.mailQueue.getMessageExceptions();
if ( enum.hasMoreElements() )
{
cW.println( "<table bgcolor=\"#E0E0E0\">" );
cW.println( "<tr>" );
cW.println( "<td bgcolor=\"#C0B0F0\">" );
cW.println( "<font size=\"+1\"><B>" );
cW.println( "The MailQueue has seen exceptions" );
cW.println( "</B></font>" );
cW.println( "</td>" );
cW.println( "</tr>" );
for ( ; enum.hasMoreElements() ; )
{
cW.println( "<tr>" );
cW.println( "<td bgcolor=\"#FFFFFF\">" );
cW.println( (String) enum.nextElement() );
cW.println( "</td>" );
cW.println( "</tr>" );
}
cW.println( "</table>" );
}
}
this.sendCommonTrailer( bReq, cW );
cW.close();
}
private void
adjustAllNextIds( BugRatRequest bReq )
throws IOException
{
PrintWriter cW = bReq.getHTMLWriter();
this.sendCommonHeader( bReq, cW, "BugRat - Admin Servlet" );
cW.println( "<h2>BugRat Adjusted Record Ids</h2>" );
try {
DBAdmin.adjustSequenceIds();
this.sendNextIdDetails( bReq, cW );
}
catch ( DBIException ex )
{
this.log( "ADJUSTING ALL SEQUENCE IDS", ex );
this.reportError( bReq, cW,
"Error adjusting the sequence IDs '"
+ ex.getMessage() + "', is sequence table defined?" );
}
this.sendCommonTrailer( bReq, cW );
cW.close();
}
private void
sendNextIdInfoPage( BugRatRequest bReq )
throws IOException
{
PrintWriter cW = bReq.getHTMLWriter();
this.sendCommonHeader( bReq, cW, "BugRat - Admin Servlet" );
cW.println( "<h2>BugRat Record Id Information</h2>" );
this.sendNextIdDetails( bReq, cW );
this.sendCommonTrailer( bReq, cW );
cW.close();
}
private void
sendNextIdDetails( BugRatRequest bReq, PrintWriter cW )
throws IOException
{
StringBuffer buf = new StringBuffer();
try {
Hashtable ids = DBAdmin.getAllSequenceIds();
cW.println( "<ul> " );
Enumeration enum = ids.keys();
for ( ; enum.hasMoreElements() ; )
{
String name = (String) enum.nextElement();
Integer nextSeq = (Integer) ids.get( name );
cW.println( "<li>" );
cW.println( "ID Name '" + name + "' " );
cW.println( "NextSequenceId = " + nextSeq.intValue() );
cW.println( "</li>" );
}
cW.println( "</ul> " );
}
catch ( DBIException ex )
{
this.reportError( bReq, cW,
"Error getting sequence IDs '"
+ ex.getMessage() + "', is sequence table defined?" );
}
}
/**
*
* editBug - display a page to allow editing of report
*
**/
private void
editBug( BugRatRequest bReq, int id )
throws IOException
{
Vector lpV = null;
PrintWriter cW = bReq.getHTMLWriter();
this.sendCommonHeader( bReq, cW, "BugRat - Edit Bug #" + id );
try {
DBConfig config = this.getDBConfig();
String bgColor = config.getProperty( "reportServlet.bgColor" );
if ( bgColor == null ) bgColor = "#E0E0E0";
String hdrColor = config.getProperty( "reportServlet.hdrColor" );
if ( hdrColor == null ) hdrColor = bgColor;
String reqColor = config.getProperty( "reportServlet.reqColor" );
if ( reqColor == null ) reqColor = "#B0E0B0";
Bug bug = Bug.getBug( id );
if ( bug == null )
{
throw new DBIException
( "Bug #" + id + " can not be found" );
}
String projectName = bug.getProject();
String categoryName = bug.getCategory();
String subCategoryName = bug.getSubCategory();
Description desc = bug.getDescription();
EnvDescription eDesc = bug.getEnvDescription();
cW.println( "<FORM method=\"POST\"" );
cW.print ( " action=\"" );
cW.print ( bReq.getServletPath() );
cW.println( "/PostEditBug" + "\">" );
cW.print ( "<INPUT type=\"hidden\" name=\"bugId\" value=\"" );
cW.print ( bug.getId() );
cW.println( "\">" );
cW.println( "<table width=\"100%\" border=\"3\" cellpadding=\"0\">" );
cW.println( "<tr bgcolor=\"#E0E0FF\">" );
cW.print ( "<td colspan=\"2\" align=\"center\" valign=\"top\" width=\"100%\" >" );
String title = "Edit Bug #" + bug.getId();
this.getOutput().sendTableTitle( bReq, cW, title );
cW.println( "</td>" );
cW.println( "</tr>" );
//
// REQUIRED FIELDS (GREEN AREA) TABLE
//
cW.println( "<tr bgcolor=\"" + reqColor + "\">" );
cW.print ( "<td align=\"center\" valign=\"top\" width=\"100%\" >" );
// P/C/S SELECTIONS IN LEFT COLUMN
cW.println( "<table width=\"100%\">" );
cW.println( "<tr>" );
cW.println( "<td width=\"100%\" align=\"left\" valign=\"top\">" );
cW.print ( "<strong>" );
cW.print ( config.getProjectName( projectName ) );
cW.print ( " / " );
cW.print ( config.getCategoryName
( projectName, categoryName ) );
cW.print ( " / " );
cW.print ( config.getSubCategoryName
( projectName, categoryName, subCategoryName ) );
cW.println( "</strong>" );
cW.println( "</td>" );
cW.println( "</tr>" );
cW.println( "<tr>" );
cW.println( "<td width=\"100%\" align=\"left\">" );
cW.println( "<SELECT NAME=\"pcs\" SIZE=12>" );
Vector projects = this.getDBConfig().getProjects();
for ( int pi = 0, psz = projects.size() ; pi < psz ; ++pi )
{
Category pc = (Category) projects.elementAt(pi);
String proj = pc.getProject();
String selprojectName = pc.getName();
Vector categories =
config.getProjectCategories( proj );
if ( pi > 0 )
cW.println( "<OPTION VALUE=\"SEP\"> --- </OPTION>" );
for ( int ci = 0, csz = categories.size() ; ci < csz ; ++ci )
{
Category cc = (Category) categories.elementAt(ci);
String cat = cc.getCategory();
String selcategoryName = cc.getName();
Vector subcats =
config.getCategorySubCats( proj, cat );
for ( int si = 0, ssz = subcats.size() ; si < ssz ;++si )
{
Category sc = (Category) subcats.elementAt(si);
String value =
sc.getProject() + "/" +
sc.getCategory() + "/" +
sc.getSubCategory();
String name =
selprojectName + " / " +
selcategoryName + " / " +
sc.getName();
if ( bug.getProject().equals( proj )
&& bug.getCategory().equals( cat )
&& bug.getSubCategory().equals
( sc.getSubCategory() ) )
{
cW.println
( "<OPTION SELECTED VALUE=\""
+ value + "\">");
}
else
{
cW.println( "<OPTION VALUE=\"" + value + "\">");
}
cW.println( name );
cW.println( "</OPTION>" );
}
}
}
cW.println( "</SELECT>" );
cW.println( "</td>" );
cW.println( "</tr>" );
cW.println( "</table>" );
cW.println( "</td>" );
// PRIORITY, ET.AL., SELECTIONS IN RIGHT COLUMN
cW.print ( "<td align=\"center\" valign=\"top\">" );
cW.println( "<table>" );
cW.println( "<tr>" );
cW.println( "<td align=\"right\">" );
cW.println( "Priority" );
cW.println( "</td>" );
cW.println( "<td width=\"100%\">" );
cW.println( "<SELECT NAME=\"priority\" SIZE=\"1\">" );
lpV = this.getDBConfig().getPriorities();
for ( int i = 0, sz = lpV.size() ; i < sz ; ++i )
{
LevelParam lp = (LevelParam) lpV.elementAt(i);
if ( lp.getId().equals( bug.getPriority() ) )
cW.println( "<OPTION SELECTED VALUE=\"" + lp.getId() + "\">" );
else
cW.println( "<OPTION VALUE=\"" + lp.getId() + "\">" );
cW.println( lp.getName() );
cW.println( "</OPTION>" );
}
cW.println( "</SELECT>" );
cW.println( "</td>" );
cW.println( "</tr>" );
cW.println( "<tr>" );
cW.println( "<td align=\"right\">" );
cW.println( "Severity" );
cW.println( "</td>" );
cW.println( "<td width=\"100%\">" );
cW.println( "<SELECT NAME=\"severity\" SIZE=\"1\">" );
lpV = this.getDBConfig().getSeverities();
for ( int i = 0, sz = lpV.size() ; i < sz ; ++i )
{
LevelParam lp = (LevelParam) lpV.elementAt(i);
if ( lp.getId().equals( bug.getSeverity() ) )
cW.println( "<OPTION SELECTED VALUE=\"" + lp.getId() + "\">" );
else
cW.println( "<OPTION VALUE=\"" + lp.getId() + "\">" );
cW.println( lp.getName() );
cW.println( "</OPTION>" );
}
cW.println( "</SELECT>" );
cW.println( "</td>" );
cW.println( "</tr>" );
cW.println( "<tr>" );
cW.println( "<td align=\"right\">" );
cW.println( "Class" );
cW.println( "</td>" );
cW.println( "<td width=\"100%\">" );
cW.println( "<SELECT NAME=\"class\" SIZE=\"1\">" );
lpV = this.getDBConfig().getClasses();
for ( int i = 0, sz = lpV.size() ; i < sz ; ++i )
{
LevelParam lp = (LevelParam) lpV.elementAt(i);
if ( lp.getId().equals( bug.getClass() ) )
cW.println( "<OPTION SELECTED VALUE=\"" + lp.getId() + "\">" );
else
cW.println( "<OPTION VALUE=\"" + lp.getId() + "\">" );
cW.println( lp.getName() );
cW.println( "</OPTION>" );
}
cW.println( "</SELECT>" );
cW.println( "</td>" );
cW.println( "</tr>" );
cW.println( "<tr>" );
cW.println( "<td align=\"right\">" );
cW.println( "Confidence" );
cW.println( "</td>" );
cW.println( "<td width=\"100%\">" );
cW.println( "<SELECT NAME=\"confidence\" SIZE=\"1\">" );
lpV = this.getDBConfig().getConfidences();
for ( int i = 0, sz = lpV.size() ; i < sz ; ++i )
{
LevelParam lp = (LevelParam) lpV.elementAt(i);
if ( lp.getId().equals( bug.getConfidence() ) )
cW.println( "<OPTION SELECTED VALUE=\"" + lp.getId() + "\">" );
else
cW.println( "<OPTION VALUE=\"" + lp.getId() + "\">" );
cW.println( lp.getName() );
cW.println( "</OPTION>" );
}
cW.println( "</SELECT>" );
cW.println( "</td>" );
cW.println( "</tr>" );
cW.println( "<tr>" );
cW.println( "<td align=\"right\">" );
cW.println( "State" );
cW.println( "</td>" );
cW.println( "<td width=\"100%\">" );
cW.println( "<SELECT NAME=\"state\" SIZE=\"1\">" );
lpV = this.getDBConfig().getStates();
for ( int i = 0, sz = lpV.size() ; i < sz ; ++i )
{
LevelParam lp = (LevelParam) lpV.elementAt(i);
if ( lp.getId().equals( bug.getState() ) )
cW.println( "<OPTION SELECTED VALUE=\"" + lp.getId() + "\">" );
else
cW.println( "<OPTION VALUE=\"" + lp.getId() + "\">" );
cW.println( lp.getName() );
cW.println( "</OPTION>" );
}
cW.println( "</SELECT>" );
cW.println( "</td>" );
cW.println( "</tr>" );
cW.println( "<tr>" );
cW.println( "<td align=\"right\">" );
cW.println( "Responsible" );
cW.println( "</td>" );
cW.println( "<td width=\"100%\">" );
String notAssgnOption =
"<OPTION VALUE=\"0\"> Not Assigned </OPTION>";
this.getOutput().sendPersonSelector
( bReq, cW, bug.getResponsible(), -1,
"responsible", notAssgnOption, null );
cW.println( "</td>" );
cW.println( "</tr>" );
Description bugDesc = bug.getDescription();
EnvDescription envDesc = bug.getEnvDescription();
cW.println( "<tr>" );
cW.println( "<td align=\"right\">" );
cW.println( "Project Release" );
cW.println( "</td>" );
cW.println( "<td>" );
cW.print ( "<INPUT type=\"text\" size=\"16\"" );
cW.print ( " name=\"release\" value=\"" );
cW.print ( (envDesc == null) ? "" : envDesc.getRelease() );
cW.println( "\">" );
cW.println( "</td>" );
cW.println( "</tr>" );
cW.println( "<tr>" );
cW.println( "<td align=\"right\">" );
cW.println( "JVM Release" );
cW.println( "</td>" );
cW.println( "<td>" );
cW.print ( "<INPUT type=\"text\" size=\"16\"" );
cW.print ( " name=\"envjvm\" value=\"" );
cW.print ( (envDesc == null) ? "" : envDesc.getJVM() );
cW.println( "\">" );
cW.println( "</td>" );
cW.println( "</tr>" );
cW.println( "<tr>" );
cW.println( "<td align=\"right\">" );
cW.println( "OS" );
cW.println( "</td>" );
cW.println( "<td>" );
cW.print ( "<INPUT type=\"text\" size=\"16\"" );
cW.print ( " name=\"envos\" value=\"" );
cW.print ( (envDesc == null) ? "" : envDesc.getOS() );
cW.println( "\">" );
cW.println( "</td>" );
cW.println( "</tr>" );
cW.println( "<tr>" );
cW.println( "<td align=\"right\">" );
cW.println( "OS Release" );
cW.println( "</td>" );
cW.println( "<td>" );
cW.print ( "<INPUT type=\"text\" size=\"16\"" );
cW.print ( " name=\"envosrel\" value=\"" );
cW.print ( (envDesc == null) ? "" : envDesc.getOSRelease() );
cW.println( "\">" );
cW.println( "</td>" );
cW.println( "</tr>" );
cW.println( "<tr>" );
cW.println( "<td align=\"right\">" );
cW.println( "Platform" );
cW.println( "</td>" );
cW.println( "<td>" );
cW.print ( "<INPUT type=\"text\" size=\"16\"" );
cW.print ( " name=\"envplat\" value=\"" );
cW.print ( (envDesc == null) ? "" : envDesc.getPlatform() );
cW.println( "\">" );
cW.println( "</td>" );
cW.println( "</tr>" );
// END of Priority table...
cW.println( "</table>" );
cW.println( "</td>" );
cW.println( "</tr>" );
cW.println( "<tr>" );
cW.println( "<td align=\"center\" colspan=\"2\" width=\"100%\">" );
cW.println( "<table border=\"0\" cellspacing=\"0\"" );
cW.println( " cellpadding=\"3\" width=\"100%\">" );
/* // Email/Name should be kept the same, i.e., not edited
cW.println( "<tr bgcolor=\"" + reqColor + "\">" );
cW.println( "<td align=\"left\">" );
cW.println( "<strong>Your Email Address:</strong>" );
cW.println( "</td>" );
cW.println( "<td align=\"left\">" );
cW.println( "<strong>Your Full Name:</strong>" );
cW.println( "</td>" );
cW.println( "</tr>" );
cW.println( "<tr bgcolor=\"" + reqColor + "\">" );
cW.println( "<td align=\"left\">" );
cW.println( "<INPUT type=\"text\" size=\"36\" name=\"emailaddr\">" );
cW.println( "</td>" );
cW.println( "<td align=\"left\">" );
cW.println( "<INPUT type=\"text\" size=\"36\" name=\"fullname\">" );
cW.println( "</td>" );
cW.println( "</tr>" );
*/
cW.println( "<tr bgcolor=\"" + reqColor + "\">" );
cW.println( "<td align=\"left\" colspan=\"2\">" );
cW.println( "<strong>Bug Synopsis (required):</strong>" );
cW.println( "</td>" );
cW.println( "</tr>" );
cW.println( "<tr bgcolor=\"" + reqColor + "\">" );
cW.println( "<td align=\"left\" colspan=\"2\">" );
cW.print ( "<INPUT type=\"text\" size=\"72\"" );
cW.print ( " name=\"synopsis\" value=\"" );
cW.print ( (bugDesc == null) ? "" : bugDesc.getSynopsis() );
cW.println( "\">" );
cW.println( "</td>" );
cW.println( "</tr>" );
cW.println( "<tr>" );
cW.println( "<td align=\"left\" colspan=\"2\">" );
cW.println( "<strong>Bug Description (optional):</strong>" );
cW.println( "</td>" );
cW.println( "</tr>" );
cW.println( "<tr>" );
cW.println( "<td align=\"left\" colspan=\"2\">" );
cW.print ( "<TEXTAREA name=\"bugdesc\" rows=\"12\" cols=\"60\">" );
cW.print ( (bugDesc == null) ? "" : bugDesc.getDescription() );
cW.println( "</TEXTAREA>" );
cW.println( "</td>" );
cW.println( "</tr>" );
cW.println( "<tr>" );
cW.println( "<td align=\"left\" colspan=\"2\">" );
cW.println( "<strong>Additional Environment Description (optional):</strong>" );
cW.println( "</td>" );
cW.println( "</tr>" );
cW.println( "<tr>" );
cW.println( "<td align=\"left\" colspan=\"2\">" );
cW.print ( "<TEXTAREA name=\"envdesc\" rows=\"3\" cols=\"60\">" );
cW.print ( (envDesc == null) ? "" : envDesc.getDescription() );
cW.println( "</TEXTAREA>" );
cW.println( "</td>" );
cW.println( "</tr>" );
cW.println( "<tr>" );
cW.println( "<td align=\"left\" colspan=\"2\">" );
cW.println( "<strong>How To Reproduce (optional):</strong>" );
cW.println( "</td>" );
cW.println( "</tr>" );
cW.println( "<tr>" );
cW.println( "<td align=\"left\" colspan=\"2\">" );
cW.print ( "<TEXTAREA name=\"repro\" rows=\"6\" cols=\"60\">" );
if ( bug.getReproDescription() != null )
cW.print ( bug.getReproDescription().getSynopsis() );
cW.println( "</TEXTAREA>" );
cW.println( "</td>" );
cW.println( "</tr>" );
cW.println( "<tr>" );
cW.println( "<td align=\"left\" colspan=\"2\">" );
cW.println( "<strong>Known Work Around (optional):</strong>" );
cW.println( "</td>" );
cW.println( "</tr>" );
cW.println( "<tr>" );
cW.println( "<td align=\"left\" colspan=\"2\">" );
cW.print ( "<TEXTAREA name=\"around\" rows=\"6\" cols=\"60\">" );
if ( bug.getAroundDescription() != null )
cW.print( bug.getAroundDescription().getSynopsis() );
cW.println( "</TEXTAREA>" );
cW.println( "</td>" );
cW.println( "</tr>" );
cW.println( "</table>" );
cW.println( "</td>" );
cW.println( "</tr>" );
cW.println( "<tr>" );
cW.println( "<td colspan=\"2\" width=\"100%\" align=\"center\">" );
cW.println( "<table width=\"100%\" cellpadding=\"8\">" );
cW.println( "<table width=\"100%\" cellpadding=\"8\">" );
cW.println( "<tr>" );
cW.println( "<td align=\"center\">" );
cW.println( "<INPUT type=\"submit\" name=\"submit\"" );
cW.println( " value=\"Submit Bug Revision\">" );
cW.println( "</td>" );
cW.println( "<td align=\"center\">" );
cW.println( "<INPUT type=\"reset\" name=\"reset\"" );
cW.println( " value=\"Clear Bug Revision\">" );
cW.println( "</td>" );
cW.println( "</tr>" );
cW.println( "</table>" );
cW.println( "</td>" );
cW.println( "</tr>" );
cW.println( "</table>" );
cW.println( "</center>" );
cW.println( "</form>" );
}
catch ( DBIException ex )
{
this.reportError
( bReq, cW,
"Could not retrieve Bug #"
+ id + ", " + ex.getMessage() );
}
this.sendCommonTrailer( bReq, cW );
cW.close();
}
/**
*
* processEditBug - process the posting of an edited bug
*
*
*/
private void
processEditBug( BugRatRequest bReq )
throws IOException
{
DBConfig config = this.getDBConfig();
String bgColor = config.getProperty( "reportServlet.bgColor" );
String okColor = config.getProperty( "reportServlet.okColor" );
String errColor = config.getProperty( "reportServlet.errColor" );
PrintWriter cW = bReq.getHTMLWriter();
this.sendCommonHeader( bReq, cW, "BugRat - Edit Bug" );
try {
String value;
String[] valAry = bReq.getParameterValues( "bugId" );
if ( this.isEmptyParameter( valAry ) )
throw this.new RequiredException( "bugID" );
//
// V A L I D A T E
// ( don't validate name/email, though since it's an edit )
//
String bugIdStr = valAry[0];
valAry = bReq.getParameterValues( "pcs" );
if ( this.isEmptyParameter( valAry ) )
throw this.new RequiredException
( "project/category/subcat" );
String pcsStr = valAry[0];
valAry = bReq.getParameterValues( "confidence" );
if ( this.isEmptyParameter( valAry ) )
throw this.new RequiredException( "confidence" );
String confStr = valAry[0];
valAry = bReq.getParameterValues( "priority" );
if ( this.isEmptyParameter( valAry ) )
throw this.new RequiredException( "priority" );
String priStr = valAry[0];
valAry = bReq.getParameterValues( "severity" );
if ( this.isEmptyParameter( valAry ) )
throw this.new RequiredException( "severity" );
String sevStr = valAry[0];
valAry = bReq.getParameterValues( "class" );
if ( this.isEmptyParameter( valAry ) )
throw this.new RequiredException( "class" );
String clsStr = valAry[0];
valAry = bReq.getParameterValues( "state" );
if ( this.isEmptyParameter( valAry ) )
throw this.new RequiredException( "state" );
String stateStr = valAry[0];
valAry = bReq.getParameterValues( "responsible" );
if ( this.isEmptyParameter( valAry ) )
throw this.new RequiredException( "responsible" );
String personStr = valAry[0];
valAry = bReq.getParameterValues( "synopsis" );
if ( this.isEmptyParameter( valAry ) )
throw this.new RequiredException( "synopsis" );
String synStr = valAry[0];
valAry = bReq.getParameterValues( "release" );
if ( this.isEmptyParameter( valAry ) )
throw this.new RequiredException( "release" );
String relStr = valAry[0];
valAry = bReq.getParameterValues( "envjvm" );
if ( this.isEmptyParameter( valAry ) )
throw this.new RequiredException( "environment JVM release" );
String jvmStr = valAry[0];
valAry = bReq.getParameterValues( "envos" );
if ( this.isEmptyParameter( valAry ) )
throw this.new RequiredException( "environment OS" );
String osStr = valAry[0];
valAry = bReq.getParameterValues( "envosrel" );
if ( this.isEmptyParameter( valAry ) )
throw this.new RequiredException( "environment OS release" );
String osRelStr = valAry[0];
valAry = bReq.getParameterValues( "envplat" );
if ( this.isEmptyParameter( valAry ) )
throw this.new RequiredException( "environment platform" );
String platStr = valAry[0];
valAry = bReq.getParameterValues( "bugdesc" );
String bugDescStr = ( valAry == null ? null : valAry[0] );
valAry = bReq.getParameterValues( "envdesc" );
String envDescStr = ( valAry == null ? null : valAry[0] );
valAry = bReq.getParameterValues( "around" );
String aroundDescStr = ( valAry == null ? null : valAry[0] );
if ( aroundDescStr != null && aroundDescStr.length() == 0 )
aroundDescStr = null;
valAry = bReq.getParameterValues( "repro" );
String reproDescStr = ( valAry == null ? null : valAry[0] );
if ( reproDescStr != null && reproDescStr.length() == 0 )
reproDescStr = null;
//
// P R O C E S S
//
int bugId = Integer.parseInt( bugIdStr );
Bug bug = Bug.getBug( bugId );
Bug saveBug = (Bug) bug.clone();
String[] cats = this.splitString( pcsStr, "/" );
bug.setProject( cats[0] );
bug.setCategory( cats[1] );
bug.setSubCategory( cats[2] );
bug.setConfidence( confStr );
bug.setPriority( priStr );
bug.setSeverity( sevStr );
bug.setBugClass( clsStr );
this.changeState( bug, stateStr );
Integer responsibleInt = new Integer ( personStr );
bug.setResponsible( responsibleInt.intValue() );
Description bugDesc = bug.getDescription();
if ( bugDesc == null )
{
bugDesc = Description.getNewDescription();
bug.setDescription( bugDesc );
}
bugDesc.setSynopsis( synStr );
bugDesc.setDescription( bugDescStr );
EnvDescription eDesc = bug.getEnvDescription();
if ( eDesc == null )
{
eDesc = Description.getNewEnvDescription();
bug.setEnvDescription( eDesc );
}
eDesc.setRelease( relStr );
eDesc.setJVM( jvmStr );
eDesc.setOS( osStr );
eDesc.setOSRelease( osRelStr );
eDesc.setPlatform( platStr );
eDesc.setDescription( envDescStr );
if ( reproDescStr != null )
{
Description repro = bug.getReproDescription();
if ( repro != null )
{
repro.setDescription( reproDescStr );
}
else
{
repro = Description.getNewDescription();
repro.setSynopsis( "Reproduce" );
repro.setDescription( reproDescStr );
bug.setReproDescription( repro );
}
}
if ( aroundDescStr != null )
{
Description around = bug.getAroundDescription();
if ( around != null )
{
around.setDescription( aroundDescStr );
}
else
{
around = Description.getNewDescription();
around.setSynopsis( "Work Around" );
around.setDescription( aroundDescStr );
bug.setAroundDescription( around );
}
}
bug.commit();
int actorId = this.getUserId( bReq );
if ( actorId == 0 )
{
this.log
( "WARNING getUserId() returned no actor "
+ "for edit bug #" + bugId );
}
// UNDONE We are not handling the case of "no changes" very well!
Description modDesc = Description.getNewDescription();
modDesc.setMimeType( "text/plain" );
modDesc.setSynopsis
( "edit bug #" + bugId
+ " by person #" + actorId );
StringBuffer buf = new StringBuffer();
bug.getDeltaDescription( saveBug, "", buf, this.getDBConfig() );
if ( buf.length() == 0 )
{
buf.append( "There appear to be no modifications." );
}
modDesc.setDescription( buf.toString() );
modDesc.commit();
BugRatAction action =
BugRatAction.getNewAction( ACTION_MODIFY );
action.setActorId( actorId );
action.setActionTime( new Date() );
action.setTarget( TARGET_BUG );
action.setTargetId( bugId );
action.setArgOne( modDesc.getId() );
action.setArgTwo( 0 );
action.setComment( modDesc.getSynopsis() );
action.commit();
try {
Person p = Person.getPerson( bug.getResponsible() );
if ( p != null )
{
this.log
( "Queueing Edit Bug Email To: '" +p.getEmail()+ "'" );
this.mailQueue.addMailJob
( modDesc.getSynopsis(),
modDesc.getDescription(),
p.getEmail(), null );
}
else
{
this.log
( "ERROR Edit Bug could not get responsible person "
+ "to email to '" + bug.getResponsible() + "'" );
}
}
catch ( MessagingException ex )
{
this.log
( "ERROR Failed sending mail notice for edit bug #"
+ bugId, ex );
}
// Generate HTML page
this.getOutput().showBug( bReq, cW, bug.getId() );
}
catch ( DBIException ex )
{
this.log( "Processing EditBug", ex );
cW.println( "<h2> Error Processing Bug </h2>" );
cW.println( "<table border=\"5\" cellpadding=\"5\">" );
cW.println( "<tr>" );
cW.println( "<td bgcolor=\"#FFFFFF\">" );
cW.println( "An error occurred trying to process your" );
cW.println( "BugRat bug. The bug was not updated," );
cW.println( "or was partially updated and needs to be" );
cW.println( "backed out. Please report the following" );
cW.println( "information to the BugRat Administrator." );
cW.println( "</td>" );
cW.println( "</tr>" );
cW.println( "<tr>" );
cW.println( "<td bgcolor=\"" + errColor + "\">" );
cW.println( "<strong>SQLException:</strong><p>" );
cW.print ( "<PRE>" );
cW.println( ex.getMessage() );
cW.println( "</PRE>" );
cW.println( "</td>" );
cW.println( "</tr>" );
cW.println( "</table>" );
}
catch ( RequiredException ex )
// UNDONE - check for bad ID exception
{
this.log
( "Missing Required Field '" + ex.getMessage() + "'", ex );
cW.println( "<h2> Missing Required Field or Bad ID</h2>" );
cW.println( "You have a missing field that is required." );
cW.println( "Please use the 'Back' key in your browser" );
cW.println( "to go back to the previous page, which will" );
cW.println( "be your partially completed bug form." );
cW.println( "Fill in the missing field and resubmit." );
cW.println( "<p>" );
cW.println( "The missing field was <strong> '" );
cW.println( ex.getMessage() + "'.</strong>" );
}
this.sendCommonTrailer( bReq, cW );
cW.close();
}
private boolean
isReportLinkedToBug( int repId, int bugId )
{
boolean result = false;
DBIManager dbiMgr = DBIManager.getInstance();
try {
result =
dbiMgr.getReportDBI().isReportLinkedToBug( repId, bugId );
}
catch ( DBIException ex )
{
ex.printStackTrace( System.err );
result = false;
}
return result;
}
private void
linkReportToBug( int repId, int bugId )
throws DBIException
{
DBIManager dbiMgr = DBIManager.getInstance();
dbiMgr.getReportDBI().linkReport( repId, bugId );
}
/** LinkReport
*
* This function determines which project a report belongs to
* then lists the bugs in that project. One is selected, and
* the report is linked to that bug in the repbug table
*
**/
private void
linkReport( BugRatRequest bReq, int repId )
throws DBIException, IOException
{
PrintWriter cW = bReq.getHTMLWriter();
this.sendCommonHeader
( bReq, cW, "BugRat - Link Report #" + repId + " To A Bug" );
cW.print ( "<h2>Select A Bug To Link Report " );
cW.print ( repId );
cW.println( " To</h2>" );
if ( this.debug )
this.log( "BugRatAdmin.linkReport: " + repId );
Report report = Report.getReport( repId );
String matchstring =
"SELECT * from bug " +
"WHERE project = '" + report.getProject() + "'";
Vector bugvector = Bug.matchBugs( matchstring );
cW.print ( "<FORM method=\"POST\" action=\"" );
cW.print ( bReq.getServletPath() );
cW.println( "/LinkReportPost\">" );
cW.println( "Report " + repId + " Synopsis:<br><br>");
cW.println( report.getDescription().getSynopsis() );
cW.println( "<br><br><br>" );
cW.print ( "<h3>Bugs in project \"" );
cW.print ( report.getProject() );
cW.println( "\":<br></h3>" );
cW.print ( "<INPUT type=\"hidden\"" );
cW.println( " name=\"report\" value=\"" + repId + "\">" );
cW.println( "<SELECT name=\"bug\" size=\"10\">" );
if ( this.debug )
this.log( "#bugs in match = " + bugvector.size());
for ( int i = 0, sz = bugvector.size() ; i < sz ; ++i )
{
Bug bug = ( Bug ) bugvector.elementAt( i );
String bugdesc =
bug.getDescription().getSynopsis();
if ( this.debug )
this.log( bugdesc );
cW.print ( "<OPTION value=\"" + bug.getId() + "\">" );
cW.println( bug.getId() + ":" + bugdesc );
}
cW.println( "<BR>");
cW.println( "<OPTION value=\"0\"> Convert To New Bug" );
cW.println( "</SELECT>" );
cW.println( "<br>" );
cW.print ( "<INPUT type=\"submit\"" );
cW.println( " name=\"submit\" value=\"Link Report to Bug\">" );
cW.println( "</FORM>" );
this.sendCommonTrailer( bReq, cW );
cW.close();
}
private void
processLinkReportPost( BugRatRequest bReq )
throws IOException
{
Bug bug = null;
PrintWriter cW = bReq.getHTMLWriter();
this.sendCommonHeader( bReq, cW, "BugRat - Link Report To A Bug" );
// UNDONE - clean up this code!
String repIdStr = bReq.getParameterValues( "report" )[0];
int repId = 0;
try { repId = Integer.parseInt( repIdStr ); }
catch ( NumberFormatException ex )
{
throw new IOException
( "can not parse report ID '" + repIdStr + "'" );
}
String[] vals = bReq.getParameterValues( "bug" );
if ( vals == null )
{
this.reportError
( bReq, cW, "You must select a project from the list" );
}
else
{
int retval;
String bugIdStr = vals[0];
this.log
( "BugRatAdmin.processLinkReport: repId = "
+ repId + ", bugId = " + bugIdStr );
int bugId = -1;
try {
bugId = Integer.parseInt( bugIdStr );
}
catch ( NumberFormatException ex )
{ bugId = -1; }
try {
boolean sendNotice = false;
Report rep = Report.getReport( repId );
if ( bugId < 0 )
{
this.getOutput().reportError( bReq, cW,
"INTERNAL ERROR, could not parse bug ID '"
+ bugIdStr + "'" );
}
else if ( bugId > 0 )
{
bug = Bug.getBug( bugId );
if ( ! this.isReportLinkedToBug( repId, bugId ) )
{
this.linkReportToBug( repId, bugId );
sendNotice = true;
}
this.getOutput().showBug( bReq, cW, bugId );
}
else
{
Bug newbug = (Bug) Bug.getNewBug();
bugId = newbug.getId();
this.linkReportToBug( repId, bugId );
// Begin copying information
newbug.setSource( rep.getSource() );
newbug.setOpenDate( new Date() );
newbug.setCloseDate( null );
newbug.setSeverity( rep.getSeverity() );
newbug.setSourceId( rep.getSourceId() );
newbug.setConfidence( rep.getConfidence() );
newbug.setPriority( rep.getPriority() );
//
// REVIEW It seems that all new bug reports should
// start out as open, regardless of the state
// of the report.
// newbug.setState( rep.getState() );
//
newbug.setState( STATE_OPEN );
newbug.setBugClass( rep.getReportClass() );
newbug.setProject( rep.getProject() );
newbug.setCategory( rep.getCategory() );
newbug.setSubCategory( rep.getSubCategory() );
int respId = rep.getResponsible();
if ( respId == 0 )
{
// If the report was not assigned to anyone, then
// assign this bug to the person linking it...
respId = this.getUserId( bReq );
}
newbug.setResponsible( respId );
Description bugdesc = newbug.getDescription();
Description repdesc = rep.getDescription();
bugdesc.setSynopsis( repdesc.getSynopsis() );
bugdesc.setEmailId( repdesc.getEmailId() );
bugdesc.setURL( repdesc.getURL() );
bugdesc.setDescription( repdesc.getDescription() );
bugdesc.setMimeType( repdesc.getMimeType() );
EnvDescription bugenvdesc = newbug.getEnvDescription();
EnvDescription repenvdesc = rep.getEnvDescription();
bugenvdesc.setRelease( repenvdesc.getRelease() );
bugenvdesc.setJVM( repenvdesc.getJVM() );
bugenvdesc.setOS( repenvdesc.getOS() );
bugenvdesc.setOSRelease( repenvdesc.getOSRelease() );
bugenvdesc.setPlatform( repenvdesc.getPlatform() );
bugenvdesc.setDescription( repenvdesc.getDescription() );
Description repReproDesc = rep.getReproDescription();
if ( repReproDesc != null )
{
Description bugReproDesc = Description.getNewDescription();
bugReproDesc.setSynopsis( repReproDesc.getSynopsis() );
newbug.setReproDescription( bugReproDesc );
}
else
{
newbug.setReproDescription( null );
}
Description repAroundDesc = rep.getAroundDescription();
if ( repAroundDesc != null )
{
Description bugAroundDesc = Description.getNewDescription();
bugAroundDesc.setSynopsis( repAroundDesc.getSynopsis() );
newbug.setAroundDescription( bugAroundDesc );
}
else
{
newbug.setAroundDescription( null );
}
newbug.commit();
// Change the report's state to 'L'inked.
rep.setState( STATE_LINKED );
rep.commit();
sendNotice = true;
bug = newbug;
this.getOutput().showBug( bReq, cW, bugId );
}
if ( sendNotice )
{
BugRatAction action =
BugRatAction.getNewAction( ACTION_LINK );
int actorId = this.getUserId( bReq );
if ( actorId == 0 )
{
this.log
( "WARNING getUserId() returned no actor "
+ "for action #" + action.getId() );
}
action.setActorId( actorId );
action.setActionTime( new Date() );
action.setTarget( TARGET_REPORT );
action.setTargetId( repId );
action.setArgOne( bugId );
action.setArgTwo( 0 );
action.setComment
( "linked report #" + repId
+ " to bug #" + bugId
+ " by person #" + actorId );
action.commit();
try {
String address = null;
String subject =
"BugRat Report #" + repId
+ " was linked to Bug #" + bugId;
StringWriter sW = new StringWriter( 4096 );
PrintWriter pW = new PrintWriter( sW );
pW.println
( "BugRat Report #" + repId
+ " was linked to Bug #" + bugId + "." );
Person p = Person.getPerson( rep.getResponsible() );
if ( p == null )
{
address = this.dbConfig.getAdminEmailAddress();
pW.println( "" );
pW.println( "*** NOTE Report #" + repId
+ " has no responsible person." );
pW.println
( "*** Mailed to the BugRat administrator, as determined" );
pW.println
( "*** by the database property 'global.adminAddress'." );
pW.println( "" );
}
else
{
address = p.getEmail();
}
pW.println( "" );
pW.println( "=== Bug Details ============================" );
this.bugFmt.format( bug, bReq, pW, "text/plain", true );
pW.println( "" );
pW.println( "=== Report Details ============================" );
this.reportFmt.format( rep, bReq, pW, "text/plain", true );
pW.close();
this.mailQueue.addMailJob
( subject, sW.toString(), address, null );
}
catch ( MessagingException ex )
{
this.log
( "Failed sending mail notice for report #"
+ repId + " link to bug #" + bugId, ex );
}
}
}
catch ( DBIException ex )
{
this.log( "LINKING REPORT", ex );
this.reportError
( bReq, cW,
"Could not link Report #"
+ repId + " to the bug, " + ex.getMessage() );
}
}
this.sendCommonTrailer( bReq, cW );
cW.close();
}
private void
changeState( Bug bug, String stateStr )
{
//
// UNDONE
// If the state changes to !CLOSED, setCloseDate(null)!
//
if ( stateStr.equals( STATE_OPEN ) )
{
// Open Bug
if ( ! bug.getState().equals( stateStr ) )
{
Date now = new Date();
bug.setOpenDate( now );
}
bug.setState( stateStr );
}
else if ( stateStr.equals( STATE_CLOSED ) )
{
// Close Bug
if ( ! bug.getState().equals( stateStr ) )
{
Date now = new Date();
bug.setCloseDate( now );
}
bug.setState( stateStr );
}
else
{
bug.setState( stateStr );
}
}
}