Home | History | Annotate | Download | only in bugzilla
      1 /**
      2  * Copyright (c) 2006 IBM Corporation and others.
      3  * All rights reserved. This program and the accompanying materials
      4  * are made available under the terms of the Eclipse Public License v1.0
      5  * which accompanies this distribution, and is available at
      6  * http://www.eclipse.org/legal/epl-v10.html
      7  */
      8 
      9 package org.eclipse.releng.services.bugzilla;
     10 
     11 
     12 import java.io.BufferedReader;
     13 import java.io.InputStreamReader;
     14 import java.io.PrintWriter;
     15 import java.net.URL;
     16 import java.net.URLConnection;
     17 import java.net.URLEncoder;
     18 import java.util.Enumeration;
     19 import java.util.Hashtable;
     20 import java.util.Iterator;
     21 import java.util.LinkedHashMap;
     22 import java.util.regex.Matcher;
     23 import java.util.regex.Pattern;
     24 
     25 import javax.net.ssl.HttpsURLConnection;
     26 
     27 import org.apache.tools.ant.BuildException;
     28 import org.apache.tools.ant.Task;
     29 
     30 import org.eclipse.releng.util.bugzilla.Messages;
     31 
     32 
     33 public class UpdateBugStateTask extends Task
     34 {
     35   private static final String UTF_8 = "UTF-8"; //$NON-NLS-1$
     36 
     37   private static final String GET = "GET"; //$NON-NLS-1$
     38 
     39   private static final String CTYPE_RDF = "&ctype=rdf"; //$NON-NLS-1$
     40 
     41   private static final String URL_TARGET_MILESTONE = "&target_milestone="; //$NON-NLS-1$
     42 
     43   private static final String URL_CHFIELDTO = "&chfieldto="; //$NON-NLS-1$
     44 
     45   private static final String URL_BUG_STATUS = "&bug_status="; //$NON-NLS-1$
     46 
     47   private static final String HTTPS_BUGS_ECLIPSE_ORG_BUGS_BUGLIST_CGI_PRODUCT = "https://bugs.eclipse.org/bugs/buglist.cgi?product="; //$NON-NLS-1$
     48 
     49   private static final String COOKIE = "Cookie"; //$NON-NLS-1$
     50 
     51   private static final String APPLICATION_X_WWW_FORM_URLENCODED = "application/x-www-form-urlencoded"; //$NON-NLS-1$
     52 
     53   private static final String CONTENT_TYPE = "Content-type"; //$NON-NLS-1$
     54 
     55   private static final String POST = "POST"; //$NON-NLS-1$
     56 
     57   private static final String HTTPS_BUGS_ECLIPSE_ORG_BUGS_PROCESS_BUG_CGI = "https://bugs.eclipse.org/bugs/process_bug.cgi"; //$NON-NLS-1$
     58 
     59   private static final String BUG_STATUS = "bug_status"; //$NON-NLS-1$
     60 
     61   private static final String AMP = "&"; //$NON-NLS-1$
     62 
     63   private static final String EQ = "="; //$NON-NLS-1$
     64 
     65   private static final String HTTPS_BUGS_ECLIPSE_ORG_BUGS_SHOW_BUG_CGI_ID = "https://bugs.eclipse.org/bugs/show_bug.cgi?id="; //$NON-NLS-1$
     66 
     67   private static final String CTYPE_XML = "&ctype=xml"; //$NON-NLS-1$
     68 
     69   private static final String RESOLVE = "resolve"; //$NON-NLS-1$
     70 
     71   private static final String RESOLUTION = "resolution"; //$NON-NLS-1$
     72 
     73   private static final String KNOB = "knob"; //$NON-NLS-1$
     74 
     75   private static final String LONGDESCLENGTH = "longdesclength"; //$NON-NLS-1$
     76 
     77   private static final String SHORT_DESC = "short_desc"; //$NON-NLS-1$
     78 
     79   private static final String BUG_FILE_LOC = "bug_file_loc"; //$NON-NLS-1$
     80 
     81   private static final String BUG_SEVERITY = "bug_severity"; //$NON-NLS-1$
     82 
     83   private static final String PRIORITY = "priority"; //$NON-NLS-1$
     84 
     85   private static final String OP_SYS = "op_sys"; //$NON-NLS-1$
     86 
     87   private static final String REP_PLATFORM = "rep_platform"; //$NON-NLS-1$
     88 
     89   private static final String TARGET_MILESTONE = "target_milestone"; //$NON-NLS-1$
     90 
     91   private static final String COMPONENT = "component"; //$NON-NLS-1$
     92 
     93   private static final String VERSION = "version"; //$NON-NLS-1$
     94 
     95   private static final String PRODUCT = "product"; //$NON-NLS-1$
     96 
     97   private static final String ID = "id"; //$NON-NLS-1$
     98 
     99   private static final String COMMENT = "comment"; //$NON-NLS-1$
    100 
    101   private static final String PROCESS_BUG = "process_bug"; //$NON-NLS-1$
    102 
    103   private static final String FORM_NAME = "form_name"; //$NON-NLS-1$
    104 
    105   private static final String BUGZILLA_LOGINCOOKIE = "; Bugzilla_logincookie="; //$NON-NLS-1$
    106 
    107   private static final String BUGZILLA_LOGIN = "Bugzilla_login="; //$NON-NLS-1$
    108 
    109   private static final String DIGITS_REGEX = "(\\d+)"; //$NON-NLS-1$
    110 
    111   private static final String COLON = ":"; //$NON-NLS-1$
    112 
    113   private static final String DASH = "-"; //$NON-NLS-1$
    114 
    115   private static final String BUGID_REGEX = "<bz:id(?: nc:parseType=\"Integer\")>(\\d+)</bz:id>"; //$NON-NLS-1$
    116 
    117   private static final String BUILDID_REGEX = "([IMNRS]?-?)(\\d{4})(\\d{2})(\\d{2})-?(\\d{2})(\\d{2})"; //$NON-NLS-1$
    118 
    119   private static final String TIMESTAMP_REGEX = "(\\d{4})(\\d{2})(\\d{2})(\\d{2})(\\d{2})"; //$NON-NLS-1$
    120 
    121   private static final String JS = "Java said:"; //$NON-NLS-1$
    122 
    123   private static final String SP = " "; //$NON-NLS-1$
    124 
    125   private static final String XML_REGEX = "<(\\S+)>([^<]+)</\\1>"; //$NON-NLS-1$
    126 
    127   private static final String NL = "\n"; //$NON-NLS-1$
    128 
    129   private static final String CSO = ", or "; //$NON-NLS-1$
    130 
    131   private static final String CS = ", "; //$NON-NLS-1$
    132 
    133   private static final String BZ_IV = "INVALID"; //$NON-NLS-1$
    134 
    135   private static final String BZ_WF = "WONTFIX"; //$NON-NLS-1$
    136 
    137   private static final String BZ_LT = "LATER"; //$NON-NLS-1$
    138 
    139   private static final String BZ_RM = "REMIND"; //$NON-NLS-1$
    140 
    141   private static final String BZ_WK = "WORKSFORME"; //$NON-NLS-1$
    142 
    143   private static final String BZ_FX = "FIXED"; //$NON-NLS-1$
    144 
    145   private static final String BZ_RE = "REOPENED"; //$NON-NLS-1$
    146 
    147   private static final String BZ_AS = "ASSIGNED"; //$NON-NLS-1$
    148 
    149   private static final String BZ_NEW = "NEW"; //$NON-NLS-1$
    150 
    151   private static final String BZ_UC = "UNCONFIRMED"; //$NON-NLS-1$
    152 
    153   private static final String EMPTY = ""; //$NON-NLS-1$
    154 
    155   private static final String LT = "<"; //$NON-NLS-1$
    156 
    157   private static final String GT = ">"; //$NON-NLS-1$
    158 
    159   private static final String QUOT = "\""; //$NON-NLS-1$
    160 
    161   private static final String APOS = "'"; //$NON-NLS-1$
    162 
    163   private static final String HTML_APOS = "&apos;"; //$NON-NLS-1$
    164 
    165   private static final String HTML_QUOT = "&quot;"; //$NON-NLS-1$
    166 
    167   private static final String HTML_LT = "&lt;"; //$NON-NLS-1$
    168 
    169   private static final String HTML_GT = "&gt;"; //$NON-NLS-1$
    170 
    171   private static final String HTML_NBSP = "&nbsp;"; //$NON-NLS-1$
    172 
    173   private static final String HTML_AMP = "&amp;"; //$NON-NLS-1$
    174 
    175   private int debug;
    176 
    177   private int login;
    178 
    179   private int loginCookie;
    180 
    181   private String product;
    182 
    183   private String status;
    184 
    185   private String buildID;
    186 
    187   private String buildAlias;
    188 
    189   private String milestone;
    190 
    191   private String bugList;
    192 
    193   private String resolution;
    194 
    195   private String endDate;
    196 
    197   private LinkedHashMap trans;
    198 
    199   public UpdateBugStateTask()
    200   {
    201     debug = 1;
    202 
    203     login = 0;
    204     loginCookie = 0;
    205     product = EMPTY;
    206     status = EMPTY;
    207     buildID = EMPTY;
    208     buildAlias = EMPTY;
    209     endDate = EMPTY;
    210     milestone = EMPTY;
    211     bugList = EMPTY;
    212     resolution = BZ_FX;
    213 
    214     trans = new LinkedHashMap(8, 0.75f, false);
    215     trans.put(HTML_APOS, APOS);
    216     trans.put(HTML_QUOT, QUOT);
    217     trans.put(HTML_LT, LT);
    218     trans.put(HTML_GT, GT);
    219     trans.put(HTML_NBSP, SP);
    220     trans.put(HTML_AMP, AMP);
    221   }
    222 
    223   public void setDebug(int d)
    224   {
    225     debug = d;
    226   }
    227 
    228   public void setBugList(String b)
    229   {
    230     bugList = b;
    231   }
    232 
    233   public void setProduct(String p)
    234   {
    235     product = p;
    236   }
    237 
    238   public void setStatus(String s)
    239   {
    240     if (s.equals(BZ_UC) || s.equals(BZ_NEW) || s.equals(BZ_AS) || s.equals(BZ_RE))
    241     {
    242       status = s;
    243     }
    244     else
    245     {
    246       throw new BuildException(Messages.getString("UpdateBugStateTask.invalidStatus") + "!" + SP + //$NON-NLS-1$ //$NON-NLS-2$
    247         Messages.getString("UpdateBugStateTask.expectedOne") + SP + BZ_UC + CS + BZ_NEW + CS + BZ_AS + CSO + BZ_RE); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
    248     }
    249   }
    250 
    251   public void setLogin(int l)
    252   {
    253     login = l;
    254   }
    255 
    256   public void setLoginCookie(int lc)
    257   {
    258     loginCookie = lc;
    259   }
    260 
    261   public void setResolution(String r)
    262   {
    263     if (r.equals(BZ_FX) || r.equals(BZ_IV) || r.equals(BZ_WF) || r.equals(BZ_LT) || r.equals(BZ_RM) || r.equals(BZ_WK))
    264     {
    265       resolution = r;
    266     }
    267     else
    268     {
    269       System.err.println(Messages.getString("UpdateBugStateTask.invalidResolution") + "!" + SP + //$NON-NLS-1$ //$NON-NLS-2$
    270         Messages.getString("UpdateBugStateTask.expected") //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
    271         + SP + BZ_FX + CS + BZ_IV + CS + BZ_WF + CS + BZ_LT + CS + BZ_RM + CSO + BZ_WK + SP
    272         + "(" + Messages.getString("UpdateBugStateTask.default") + COLON + SP + BZ_FX + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
    273     }
    274   }
    275 
    276   public void setEndDate(String t)
    277   {
    278     Pattern p = Pattern.compile(TIMESTAMP_REGEX);
    279     Matcher m = p.matcher(t);
    280     if (m.matches())
    281     {
    282       endDate = m.group(1) + DASH + m.group(2) + DASH + m.group(3) + SP + m.group(4) + COLON + m.group(5);
    283     }
    284     else
    285     {
    286       throw new BuildException(Messages.getString("UpdateBugStateTask.invalidTimestamp") + COLON + SP + t + "!"); //$NON-NLS-1$ //$NON-NLS-2$
    287     }
    288   }
    289 
    290   public void setBuildID(String t)
    291   {
    292     Pattern p = Pattern.compile(BUILDID_REGEX);
    293     Matcher m = p.matcher(t);
    294     if (m.matches())
    295     {
    296       buildID = m.group(1) + m.group(2) + m.group(3) + m.group(4) + m.group(5) + m.group(6);
    297     }
    298     else
    299     {
    300       throw new BuildException(Messages.getString("UpdateBugStateTask.invalidBuildID") + COLON + SP + t + "!"); //$NON-NLS-1$ //$NON-NLS-2$
    301     }
    302   }
    303 
    304   public void setBuildAlias(String b)
    305   {
    306     buildAlias = b;
    307   }
    308 
    309   public void setMilestone(String m)
    310   {
    311     milestone = m;
    312   }
    313 
    314 public void execute() throws BuildException
    315   {
    316     if (login == 0)
    317     {
    318       throw new BuildException(Messages.getString("UpdateBugStateTask.expectingLogin") + "!"); //$NON-NLS-1$ //$NON-NLS-2$
    319     }
    320     if (loginCookie == 0)
    321     {
    322       throw new BuildException(Messages.getString("UpdateBugStateTask.expectingLogincookie") + "!"); //$NON-NLS-1$ //$NON-NLS-2$
    323     }
    324     if (status.equals(EMPTY))
    325     {
    326       throw new BuildException(Messages.getString("UpdateBugStateTask.expectingStatus") + "!"); //$NON-NLS-1$ //$NON-NLS-2$
    327     }
    328 
    329     /* we take an explicit list OR do a query, not both */
    330     if (!bugList.equals(EMPTY) && endDate.equals(EMPTY) && milestone.equals(EMPTY) && product.equals(EMPTY))
    331     {
    332       if (debug > 1)
    333       {
    334         System.err.println(Messages.getString("UpdateBugStateTask.usingBugList")); //$NON-NLS-1$
    335       }
    336       Pattern p = Pattern.compile(DIGITS_REGEX);
    337       Matcher m = p.matcher(bugList);
    338       while (m.find())
    339       {
    340         int bugID = Integer.parseInt(m.group(1));
    341         if (debug > 1)
    342         {
    343           System.err.println(Messages.getString("UpdateBugStateTask.found") + SP + bugID); //$NON-NLS-1$
    344         }
    345         doBug(bugID);
    346       }
    347     }
    348     else if (bugList.equals(EMPTY))
    349     {
    350       if (product.equals(EMPTY))
    351       {
    352         throw new BuildException(Messages.getString("UpdateBugStateTask.expectingProduct") + "!"); //$NON-NLS-1$ //$NON-NLS-2$
    353       }
    354 
    355       if (debug > 1)
    356       {
    357         System.err.println(Messages.getString("UpdateBugStateTask.queryingFor") + SP + //$NON-NLS-1$
    358           (!status.equals(EMPTY) ? status + SP : EMPTY) +
    359           (!product.equals(EMPTY) ? product + SP : EMPTY) +
    360           (!milestone.equals(EMPTY) ? milestone + SP : EMPTY) +
    361           Messages.getString("UpdateBugStateTask.bugs")); //$NON-NLS-1$ //$NON-NLS-2$
    362       }
    363 
    364       /* the Bugzilla search form generates a massive URL, but thankfully doesn't
    365        * demand all sorts of superfluous fields like when updating a bug */
    366       String url = HTTPS_BUGS_ECLIPSE_ORG_BUGS_BUGLIST_CGI_PRODUCT + urlEncode(product) + URL_BUG_STATUS + urlEncode(status)
    367         + URL_CHFIELDTO + urlEncode(endDate) + URL_TARGET_MILESTONE + urlEncode(milestone) + CTYPE_RDF;
    368       if (debug > 1)
    369       {
    370         System.err.println(Messages.getString("UpdateBugStateTask.connectingTo") + SP + //$NON-NLS-1$
    371           url + SP + "..."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
    372       }
    373       HttpsURLConnection bugsconn = getConn(url, GET, true, false, EMPTY);
    374       String bugs = slurpStream(bugsconn);
    375       if (debug > 1)
    376       {
    377         System.err.println(Messages.getString("UpdateBugStateTask.gotBugList") + COLON); //$NON-NLS-1$
    378         System.err.println(bugs);
    379       }
    380 
    381       Pattern p = Pattern.compile(BUGID_REGEX);
    382       Matcher m = p.matcher(bugs);
    383       if (m.find()) {
    384         while (m.find())
    385         {
    386           int bugID = Integer.parseInt(m.group(1));
    387           if (debug > 1)
    388           {
    389             System.out.println(Messages.getString("UpdateBugStateTask.found") + SP + bugID); //$NON-NLS-1$
    390           }
    391           doBug(bugID);
    392         }
    393       }
    394       else
    395       {
    396         System.out.println("No bugs found matching specified state" + SP + "(" + status + "). Nothing to do!");
    397       }
    398     }
    399     else
    400     {
    401       throw new BuildException(Messages.getString("UpdateBugStateTask.ambiguousRequest") + CS + //$NON-NLS-1$
    402         Messages.getString("UpdateBugStateTask.mutuallyExclusive") + "!"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
    403     }
    404   }  private void doBug(int bugID) throws BuildException
    405   {
    406     if (bugID == 0)
    407     {
    408       throw new BuildException(Messages.getString("UpdateBugStateTask.invalidBugID") + SP + bugID + "!"); //$NON-NLS-1$ //$NON-NLS-2$
    409     }
    410 
    411     String bugcookie = BUGZILLA_LOGIN + login + BUGZILLA_LOGINCOOKIE + loginCookie;
    412     String buildstring = EMPTY;
    413     if (buildAlias.equals(EMPTY) && buildID.equals(EMPTY))
    414     {
    415       buildstring = Messages.getString("UpdateBugStateTask.latestBuild"); //$NON-NLS-1$
    416     }
    417     else if (!buildAlias.equals(EMPTY) && !buildID.equals(EMPTY))
    418     {
    419       buildstring = buildAlias + SP + "(" + buildID + ")"; //$NON-NLS-1$ //$NON-NLS-2$
    420     }
    421     else
    422     {
    423       buildstring = (!buildAlias.equals(EMPTY) ? buildAlias : buildID);
    424     }
    425 
    426     Hashtable args = new Hashtable();
    427     args.put(FORM_NAME, PROCESS_BUG);
    428     args.put(COMMENT, Messages.getString("UpdateBugStateTask.fixedIn") + SP + buildstring + "."); //$NON-NLS-1$ //$NON-NLS-2$
    429     args.put(ID, new Integer(bugID));
    430     args.put(PRODUCT, EMPTY);
    431     args.put(VERSION, EMPTY);
    432     args.put(COMPONENT, EMPTY);
    433     args.put(TARGET_MILESTONE, EMPTY);
    434     args.put(REP_PLATFORM, EMPTY);
    435     args.put(OP_SYS, EMPTY);
    436     args.put(PRIORITY, EMPTY);
    437     args.put(BUG_SEVERITY, EMPTY);
    438     args.put(BUG_FILE_LOC, EMPTY);
    439     args.put(SHORT_DESC, EMPTY);
    440     args.put(LONGDESCLENGTH, new Integer(1)); //Bugzilla doesn't seem to use this, but demands it anyways
    441     args.put(KNOB, RESOLVE);
    442     args.put(RESOLUTION, resolution);
    443 
    444     if (debug > 1)
    445     {
    446       System.err.println(Messages.getString("UpdateBugStateTask.usingCookie") + COLON + SP + bugcookie); //$NON-NLS-1$
    447       System.err.println(Messages.getString("UpdateBugStateTask.usingComment") + COLON + SP + args.get(COMMENT).toString()); //$NON-NLS-1$
    448     }
    449 
    450     /* slurp xml for bugID */
    451     String url = HTTPS_BUGS_ECLIPSE_ORG_BUGS_SHOW_BUG_CGI_ID + urlEncode(args.get(ID).toString()) + CTYPE_XML;
    452     if (debug > 1)
    453     {
    454       System.err.println(Messages.getString("UpdateBugStateTask.connectingTo") + SP + //$NON-NLS-1$
    455         url + SP + "..."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
    456     }
    457     HttpsURLConnection xmlconn = getConn(url, GET, true, false, EMPTY);
    458     String xml = slurpStream(xmlconn);
    459     if (debug > 1)
    460     {
    461       System.err.println(Messages.getString("UpdateBugStateTask.gotXML") + COLON); //$NON-NLS-1$
    462       System.err.println(xml);
    463     }
    464     xmlconn.disconnect();
    465 
    466     /* parse xml, build post string */
    467     String req = EMPTY;
    468     Hashtable pxml = parseXML(xml);
    469     for (Enumeration e = args.keys(); e.hasMoreElements();)
    470     {
    471       String elem = e.nextElement().toString();
    472       /* sometimes Bugzilla omits bug_file_loc if it's blank... */
    473       if (args.get(elem).equals(EMPTY) && pxml.get(elem) != null)
    474       {
    475         args.put(elem, pxml.get(elem));
    476       }
    477 
    478       req += urlEncode(elem) + EQ + urlEncode(args.get(elem).toString()) + AMP;
    479     }
    480 
    481     req = req.substring(0, req.length() - 1);
    482 
    483     /* update bug, if applicable */
    484     if (pxml.get(BUG_STATUS) == null)
    485     {
    486       if (debug > 0)
    487       {
    488         System.out.println(Messages.getString("UpdateBugStateTask.noBugStatus") + SP + //$NON-NLS-1$
    489           bugID + CS + Messages.getString("UpdateBugStateTask.missingBug")); //$NON-NLS-1$ //$NON-NLS-2$
    490       }
    491     }
    492     else if (pxml.get(BUG_STATUS).equals(status))
    493     {
    494       String bugurl = HTTPS_BUGS_ECLIPSE_ORG_BUGS_PROCESS_BUG_CGI;
    495       if (debug > 1)
    496       {
    497         System.err.println(Messages.getString("UpdateBugStateTask.connectingTo") + SP + //$NON-NLS-1$
    498           bugurl + SP + "..."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
    499       }
    500       HttpsURLConnection bugconn = getConn(bugurl, POST, true, true, bugcookie);
    501 
    502       if (debug > 1)
    503       {
    504         System.err.println(Messages.getString("UpdateBugStateTask.postingData") + COLON); //$NON-NLS-1$
    505         System.err.println(req);
    506       }
    507       sendStream(bugconn, req);
    508       String response = slurpStream(bugconn);
    509 
    510       // trap for invalid login cookie
    511       if (response.indexOf(Messages.getString("UpdateBugStateTask.legitimateLoginAndPassword")) > 0) //$NON-NLS-1$
    512       {
    513         System.err.println(Messages.getString("UpdateBugStateTask.couldNotLogIn")); //$NON-NLS-1$
    514         System.err.println(Messages.getString("UpdateBugStateTask.BugzillaReplied") + COLON + SP + //$NON-NLS-1$
    515           "\"" + Messages.getString("UpdateBugStateTask.legitimateLoginAndPassword") + "\""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
    516         if (debug > 1)
    517         {
    518           System.err.println(Messages.getString("UpdateBugStateTask.gotResponse") + COLON); //$NON-NLS-1$
    519           System.err.println(response);
    520         }
    521         bugconn.disconnect();
    522         System.err.println(Messages.getString("UpdateBugStateTask.setBugFailed") + SP + bugID + SP + //$NON-NLS-1$
    523           Messages.getString("UpdateBugStateTask.to") + SP + resolution + SP + //$NON-NLS-1$
    524           "(" + Messages.getString("UpdateBugStateTask.was") + SP + pxml.get(BUG_STATUS) + ")" + COLON + SP + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
    525           "\"" + Messages.getString("UpdateBugStateTask.fixedIn") + SP + buildstring + ".\""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
    526       }
    527       else
    528       {
    529         if (debug > 1)
    530         {
    531           System.err.println(Messages.getString("UpdateBugStateTask.gotResponse") + COLON); //$NON-NLS-1$
    532           System.err.println(response);
    533         }
    534         bugconn.disconnect();
    535         if (debug > 0)
    536         {
    537           System.out.println(Messages.getString("UpdateBugStateTask.setBug") + SP + bugID + SP + //$NON-NLS-1$
    538             Messages.getString("UpdateBugStateTask.to") + SP + resolution + SP + //$NON-NLS-1$
    539             "(" + Messages.getString("UpdateBugStateTask.was") + SP + pxml.get(BUG_STATUS) + ")" + COLON + SP + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
    540             "\"" + Messages.getString("UpdateBugStateTask.fixedIn") + SP + buildstring + ".\""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
    541         }
    542       }
    543     }
    544     else
    545     {
    546       if (debug > 0)
    547       {
    548         System.out.println(Messages.getString("UpdateBugStateTask.ignoreBug") + SP + args.get(ID).toString() + SP + //$NON-NLS-1$
    549           "(" + Messages.getString("UpdateBugStateTask.notInExpectedState") + SP + status + ")" + COLON + SP + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
    550           Messages.getString("UpdateBugStateTask.was") + SP + pxml.get(BUG_STATUS).toString() + "."); //$NON-NLS-1$ //$NON-NLS-2$
    551       }
    552     }
    553   }
    554 
    555   private String urlEncode(String elem)
    556   {
    557     elem = htmlDecode(elem);
    558 
    559     try
    560     {
    561       elem = URLEncoder.encode(elem, UTF_8);
    562     }
    563     catch (java.io.UnsupportedEncodingException e)
    564     {
    565       throw new BuildException(Messages.getString("UpdateBugStateTask.couldntEncode") + SP + //$NON-NLS-1$
    566         "'" + elem + "'" + "!" + SP + JS + SP + e.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
    567     }
    568 
    569     return elem;
    570   }
    571 
    572   private HttpsURLConnection getConn(String url, String method, boolean in, boolean out, String cookie)
    573   {
    574     URL u = null;
    575     try
    576     {
    577       u = new URL(url);
    578     }
    579     catch (java.net.MalformedURLException e)
    580     {
    581       throw new BuildException(Messages.getString("UpdateBugStateTask.badURL") + CS + //$NON-NLS-1$
    582         url + "!" + SP + JS + SP + e.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
    583     }
    584 
    585     URLConnection conn = null;
    586     try
    587     {
    588       conn = u.openConnection();
    589     }
    590     catch (java.io.IOException e)
    591     {
    592       throw new BuildException(Messages.getString("UpdateBugStateTask.failedConnection") + "!" + SP + JS + SP + e.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
    593     }
    594     HttpsURLConnection sconn = (HttpsURLConnection)conn;
    595 
    596     try
    597     {
    598       sconn.setRequestMethod(method);
    599     }
    600     catch (java.net.ProtocolException e)
    601     {
    602       throw new BuildException(Messages.getString("UpdateBugStateTask.badHTTPMethod") + "!" + SP + JS + SP + e.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
    603     }
    604 
    605     if (method.equals(POST))
    606     {
    607       sconn.setRequestProperty(CONTENT_TYPE, APPLICATION_X_WWW_FORM_URLENCODED);
    608     }
    609 
    610     if (!cookie.equals(EMPTY))
    611     {
    612       sconn.setRequestProperty(COOKIE, cookie);
    613     }
    614 
    615     sconn.setDoInput(in);
    616     sconn.setDoOutput(out);
    617 
    618     try
    619     {
    620       sconn.connect();
    621     }
    622     catch (java.io.IOException e)
    623     {
    624       throw new BuildException(Messages.getString("UpdateBugStateTask.connectError") + SP + //$NON-NLS-1$
    625         url + "!" + SP + JS + SP + e.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
    626     }
    627 
    628     return sconn;
    629   }
    630 
    631   private void sendStream(HttpsURLConnection conn, String req)
    632   {
    633     try
    634     {
    635       PrintWriter out = new PrintWriter(conn.getOutputStream());
    636       out.print(req);
    637       out.flush();
    638       out.close();
    639     }
    640     catch (java.io.IOException e)
    641     {
    642       throw new BuildException(Messages.getString("UpdateBugStateTask.streamWriteError") + "!" + SP + JS + SP + e.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
    643     }
    644   }
    645 
    646   private String slurpStream(HttpsURLConnection conn)
    647   {
    648     String ret = EMPTY;
    649     try
    650     {
    651       BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
    652       String tmp;
    653       while ((tmp = in.readLine()) != EMPTY && tmp != null)
    654       {
    655         ret += tmp + NL;
    656       }
    657 
    658       in.close();
    659     }
    660     catch (java.io.IOException e)
    661     {
    662       throw new BuildException(Messages.getString("UpdateBugStateTask.streamReadError") + "!" + SP + JS + SP + e.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
    663     }
    664 
    665     return ret;
    666   }
    667 
    668   /* this will only keep the last comment, but we don't use the comments anyways */
    669   private Hashtable parseXML(String xml)
    670   {
    671     if (debug > 1)
    672     {
    673       System.err.println(Messages.getString("UpdateBugStateTask.parsingXML") + "..."); //$NON-NLS-1$ //$NON-NLS-2$
    674     }
    675     Hashtable pxml = new Hashtable();
    676     Pattern p = Pattern.compile(XML_REGEX);
    677     Matcher m = p.matcher(xml);
    678     while (m.find())
    679     {
    680       if (debug > 1)
    681       {
    682         System.err.println(Messages.getString("UpdateBugStateTask.found") + SP + m.group(1) + SP + EQ + SP + m.group(2)); //$NON-NLS-1$
    683       }
    684       pxml.put(m.group(1), m.group(2));
    685     }
    686 
    687     return pxml;
    688   }
    689 
    690   private String htmlDecode(String str)
    691   {
    692     for (Iterator i = trans.keySet().iterator(); i.hasNext();)
    693     {
    694       String elem = i.next().toString();
    695 
    696       str = Pattern.compile(elem).matcher(str).replaceAll(trans.get(elem).toString());
    697     }
    698 
    699     return str;
    700   }
    701 
    702   public static void main(String args[])
    703   {
    704     new UpdateBugStateTask();
    705   }
    706 }
    707