Changeset 1137 in josm for trunk


Ignore:
Timestamp:
2008-12-15T00:45:00+01:00 (15 years ago)
Author:
framm
Message:
  • some API 0.6 error return fixes; closes #1810
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/io/OsmServerWriter.java

    r1071 r1137  
    5050public class OsmServerWriter extends OsmConnection implements Visitor {
    5151
    52         /**
    53          * This list contain all successful processed objects. The caller of
    54         * upload* has to check this after the call and update its dataset.
    55         *
    56         * If a server connection error occurs, this may contain fewer entries
    57         * than where passed in the list to upload*.
    58         */
    59         public Collection<OsmPrimitive> processed;
    60 
    61         /**
    62         * Whether the operation should be aborted as soon as possible.
    63         */
    64         // use the inherited variable
    65         // private boolean cancel = false;
    66 
    67         /**
    68         * Object describing current changeset
    69         */
    70         private Changeset changeset;
    71 
    72         /**
    73         * Send the dataset to the server. Ask the user first and does nothing if he
    74         * does not want to send the data.
    75         */
    76         private static final int MSECS_PER_SECOND = 1000;
    77         private static final int SECONDS_PER_MINUTE = 60;
    78         private static final int MSECS_PER_MINUTE = MSECS_PER_SECOND * SECONDS_PER_MINUTE;
    79 
    80         long uploadStartTime;
    81    
    82         public String timeLeft(int progress, int list_size) {
    83                 long now = System.currentTimeMillis();
    84                 long elapsed = now - uploadStartTime;
    85                 if (elapsed == 0)
    86                         elapsed = 1;
    87                 float uploads_per_ms = (float)progress / elapsed;
    88                 float uploads_left = list_size - progress;
    89                 int ms_left = (int)(uploads_left / uploads_per_ms);
    90                 int minutes_left = ms_left / MSECS_PER_MINUTE;
    91                 int seconds_left = (ms_left / MSECS_PER_SECOND) % SECONDS_PER_MINUTE ;
    92                 String time_left_str = Integer.toString(minutes_left) + ":";
    93                 if (seconds_left < 10)
    94                         time_left_str += "0";
    95                 time_left_str += Integer.toString(seconds_left);
    96                 return time_left_str;
    97         }
    98    
    99         public void uploadOsm(Collection<OsmPrimitive> list) throws SAXException {
    100                 processed = new LinkedList<OsmPrimitive>();
    101                 initAuthentication();
    102 
    103                 Main.pleaseWaitDlg.progress.setMaximum(list.size());
    104                 Main.pleaseWaitDlg.progress.setValue(0);
    105                
     52    /**
     53     * This list contains all successfully processed objects. The caller of
     54    * upload* has to check this after the call and update its dataset.
     55    *
     56    * If a server connection error occurs, this may contain fewer entries
     57    * than where passed in the list to upload*.
     58    */
     59    public Collection<OsmPrimitive> processed;
     60
     61    /**
     62    * Whether the operation should be aborted as soon as possible.
     63    */
     64    // use the inherited variable
     65    // private boolean cancel = false;
     66
     67    /**
     68    * Object describing current changeset
     69    */
     70    private Changeset changeset;
     71
     72    /**
     73    * Send the dataset to the server. Ask the user first and does nothing if he
     74    * does not want to send the data.
     75    */
     76    private static final int MSECS_PER_SECOND = 1000;
     77    private static final int SECONDS_PER_MINUTE = 60;
     78    private static final int MSECS_PER_MINUTE = MSECS_PER_SECOND * SECONDS_PER_MINUTE;
     79
     80    long uploadStartTime;
     81   
     82    public String timeLeft(int progress, int list_size) {
     83        long now = System.currentTimeMillis();
     84        long elapsed = now - uploadStartTime;
     85        if (elapsed == 0)
     86            elapsed = 1;
     87        float uploads_per_ms = (float)progress / elapsed;
     88        float uploads_left = list_size - progress;
     89        int ms_left = (int)(uploads_left / uploads_per_ms);
     90        int minutes_left = ms_left / MSECS_PER_MINUTE;
     91        int seconds_left = (ms_left / MSECS_PER_SECOND) % SECONDS_PER_MINUTE ;
     92        String time_left_str = Integer.toString(minutes_left) + ":";
     93        if (seconds_left < 10)
     94            time_left_str += "0";
     95        time_left_str += Integer.toString(seconds_left);
     96        return time_left_str;
     97    }
     98   
     99    public void uploadOsm(Collection<OsmPrimitive> list) throws SAXException {
     100        processed = new LinkedList<OsmPrimitive>();
     101        initAuthentication();
     102
     103        Main.pleaseWaitDlg.progress.setMaximum(list.size());
     104        Main.pleaseWaitDlg.progress.setValue(0);
     105       
    106106        // controls whether or not we open and close a changeset. API 0.6 requires changesets.
    107                 boolean useChangesets = Main.pref.get("osm-server.version", "0.5").equals("0.6");
     107        boolean useChangesets = Main.pref.get("osm-server.version", "0.5").equals("0.6");
    108108       
    109109        // controls whether or not we try and uplaod the whole bunch in one go
     
    111111            Main.pref.get("osm-server.version", "0.5").equals("0.6"));
    112112       
    113                 String comment = null;
    114                 while (useChangesets && comment == null) {
    115                         comment = JOptionPane.showInputDialog(Main.parent, tr("Provide a brief comment as to the changes to you are uploading:"),
    116                          tr("Commit comment"), JOptionPane.QUESTION_MESSAGE);
    117                         if( comment == null )
    118                                 return;
    119                         /* Don't let people just hit enter */
    120                         if( comment.trim().length() >= 3 )
    121                                 break;
    122                         comment = null;
    123                 }
    124                 try {
    125                         if (useChangesets && !startChangeset(10, comment))
    126                                 return;
    127                 }
    128                 catch (OsmTransferException ex) {
    129                         dealWithTransferException(ex);
    130                         return;
    131                 }
    132        
    133                 try {
     113        String comment = null;
     114        while (useChangesets && comment == null) {
     115            comment = JOptionPane.showInputDialog(Main.parent,
     116                 tr("Provide a brief comment as to the changes to you are uploading:"),
     117                 tr("Commit comment"), JOptionPane.QUESTION_MESSAGE);
     118            if (comment == null)
     119                return;
     120            /* Don't let people just hit enter */
     121            if( comment.trim().length() >= 3 )
     122                break;
     123            comment = null;
     124        }
     125        try {
     126            if (useChangesets && !startChangeset(10, comment))
     127                return;
     128        }
     129        catch (OsmTransferException ex) {
     130            dealWithTransferException(ex);
     131            return;
     132        }
     133   
     134        try {
    134135            if (useDiffUploads) {
    135136                uploadDiff(10, list);
     
    149150                }
    150151            }
    151                         if (useChangesets)
    152                             stopChangeset(10);
    153                 } catch (RuntimeException e) {
    154                         try {
    155                                 if (useChangesets)
    156                     stopChangeset(10);
    157                         }
    158                         catch (OsmTransferException ex) {
    159                                 dealWithTransferException(ex);
    160                         }
    161                         e.printStackTrace();
    162                         throw new SAXException(tr("An error occoured: {0}",e.getMessage()));
    163                 }
    164                 catch (OsmTransferException e) {
    165                         try {
    166                                 if( useChangesets ) stopChangeset(10);
    167                         }
    168                         catch (OsmTransferException ex) {
    169                                 dealWithTransferException(ex); 
    170                         }
    171                         dealWithTransferException(e);
    172                 }
    173         }
    174        
    175         /* FIXME: This code is terrible, please fix it!!!! */
    176 
    177         /* Ok, this needs some explanation: The problem is that the code for
    178          * retrying requests is intertwined with the code that generates the
    179          * actual request. This means that for the retry code for the
    180          * changeset stuff, it's basically a copy/cut/change slightly
    181          * process. What actually needs to happen is that the retrying needs
    182          * to be split from the creation of the requests and the retry loop
    183          * handled in one place (preferably without recursion). While at you
    184          * can fix the issue where hitting cancel doesn't do anything while
    185          * retrying. - Mv0 Apr 2008
    186          *
    187          * Cancelling has an effect now, maybe it does not always catch on. Florian Heer, Aug 08
    188          */
    189         private boolean startChangeset(int retries, String comment) throws OsmTransferException {
    190                 Main.pleaseWaitDlg.currentAction.setText(tr("Opening changeset..."));
    191                 changeset = new Changeset();
    192                 changeset.put( "created_by", "JOSM" );
    193                 changeset.put( "comment", comment );
    194                 try {
    195                         if (cancel)
    196                                 return false; // assume cancel
    197                         String version = Main.pref.get("osm-server.version", "0.6");
    198                         URL url = new URL(
    199                                         Main.pref.get("osm-server.url") +
    200                                         "/" + version +
    201                                         "/" + "changeset" +
    202                                         "/" + "create");
    203                         System.out.print("upload to: "+url+ "..." );
    204                         activeConnection = (HttpURLConnection)url.openConnection();
    205                         activeConnection.setConnectTimeout(15000);
    206                         activeConnection.setRequestMethod("PUT");
    207                         addAuth(activeConnection);
    208                        
    209                         activeConnection.setDoOutput(true);
    210                         OutputStream out = activeConnection.getOutputStream();
    211                         OsmWriter.output(out, changeset);
    212                         out.close();
    213                        
    214                         activeConnection.connect();
    215                         System.out.println("connected");
    216 
    217                         int retCode = activeConnection.getResponseCode();
    218                         if (retCode == 200)
    219                                 changeset.id = readId(activeConnection.getInputStream());
    220                         System.out.println("got return: "+retCode+" with id "+changeset.id);
    221                         String retMsg = activeConnection.getResponseMessage();
    222                         activeConnection.disconnect();
    223                         if (retCode == 404)
    224                         {
    225                                 System.out.println("Server does not support changesets, continuing");
    226                                 return true;
    227                         }
    228                         if (retCode != 200 && retCode != 412) {
     152            if (useChangesets) stopChangeset(10);
     153        } catch (RuntimeException e) {
     154            try {
     155                if (useChangesets) stopChangeset(10);
     156            }
     157            catch (OsmTransferException ex) {
     158                dealWithTransferException(ex);
     159            }
     160            e.printStackTrace();
     161            throw new SAXException(tr("An error occoured: {0}",e.getMessage()));
     162        }
     163        catch (OsmTransferException e) {
     164            try {
     165                if (useChangesets) stopChangeset(10);
     166            }
     167            catch (OsmTransferException ex) {
     168                dealWithTransferException(ex);   
     169            }
     170            dealWithTransferException(e);
     171        }
     172    }
     173   
     174    /* FIXME: This code is terrible, please fix it!!!! */
     175
     176    /* Ok, this needs some explanation: The problem is that the code for
     177     * retrying requests is intertwined with the code that generates the
     178     * actual request. This means that for the retry code for the
     179     * changeset stuff, it's basically a copy/cut/change slightly
     180     * process. What actually needs to happen is that the retrying needs
     181     * to be split from the creation of the requests and the retry loop
     182     * handled in one place (preferably without recursion). While at you
     183     * can fix the issue where hitting cancel doesn't do anything while
     184     * retrying. - Mv0 Apr 2008
     185     *
     186     * Cancelling has an effect now, maybe it does not always catch on. Florian Heer, Aug 08
     187     */
     188    private boolean startChangeset(int retries, String comment) throws OsmTransferException {
     189        Main.pleaseWaitDlg.currentAction.setText(tr("Opening changeset..."));
     190        changeset = new Changeset();
     191        changeset.put( "created_by", "JOSM" );
     192        changeset.put( "comment", comment );
     193        try {
     194            if (cancel)
     195                return false; // assume cancel
     196            String version = Main.pref.get("osm-server.version", "0.6");
     197            URL url = new URL(
     198                    Main.pref.get("osm-server.url") +
     199                    "/" + version +
     200                    "/" + "changeset" +
     201                    "/" + "create");
     202            System.out.print("upload to: "+url+ "..." );
     203            activeConnection = (HttpURLConnection)url.openConnection();
     204            activeConnection.setConnectTimeout(15000);
     205            activeConnection.setRequestMethod("PUT");
     206            addAuth(activeConnection);
     207           
     208            activeConnection.setDoOutput(true);
     209            OutputStream out = activeConnection.getOutputStream();
     210            OsmWriter.output(out, changeset);
     211            out.close();
     212           
     213            activeConnection.connect();
     214            System.out.println("connected");
     215
     216            int retCode = activeConnection.getResponseCode();
     217            if (retCode == 200)
     218                changeset.id = readId(activeConnection.getInputStream());
     219            System.out.println("got return: "+retCode+" with id "+changeset.id);
     220            String retMsg = activeConnection.getResponseMessage();
     221            activeConnection.disconnect();
     222            if (retCode == 404)    {
     223                throw new OsmTransferException(tr("Server does not support changesets"));
     224            }
     225            if (retCode != 200 && retCode != 412) {
    229226               
    230                                 if (retries >= 0) {
    231                                         retries--;
    232                                         System.out.print("backing off for 10 seconds...");
    233                                         Thread.sleep(10000);
    234                                         System.out.println("retrying ("+retries+" left)");
    235                                         return startChangeset(retries, comment);
    236                                 }
     227                if (retries >= 0) {
     228                    retries--;
     229                    System.out.print("backing off for 10 seconds...");
     230                    Thread.sleep(10000);
     231                    System.out.println("retrying ("+retries+" left)");
     232                    return startChangeset(retries, comment);
     233                }
    237234               
    238                                 // Look for a detailed error message from the server
    239                                 if (activeConnection.getHeaderField("Error") != null)
    240                                     retMsg += "\n" + activeConnection.getHeaderField("Error");
    241 
    242                                 // Report our error
    243                                 ByteArrayOutputStream o = new ByteArrayOutputStream();
    244                                 OsmWriter.output(o, changeset);
    245                                 System.out.println(new String(o.toByteArray(), "UTF-8").toString());
    246                                 //throw new RuntimeException(retCode+" "+retMsg);
    247                                 throw new OsmTransferException (retCode + " " + retMsg);
    248                        
    249                         }
    250                 } catch (UnknownHostException e) {
    251                         //throw new RuntimeException(tr("Unknown host")+": "+e.getMessage(), e);
    252                         throw new OsmTransferException(tr("Unknown host")+": "+e.getMessage(), e);
    253                 } catch(SocketTimeoutException e) {
    254                         System.out.println(" timed out, retries left: " + retries);
    255                         if (cancel)
    256                                 return false; // assume cancel
    257                         if (retries-- > 0)
    258                                 startChangeset(retries, comment);
    259                         else
    260                                 // throw new RuntimeException (e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
    261                                 throw new OsmTransferException (e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
    262                 }
    263                 catch (ConnectException e) {
    264                         System.out.println(" timed out, retries left: " + retries);
    265                         if (cancel)
    266                                 return false; // assume cancel
    267                         if (retries-- > 0)
    268                                 startChangeset(retries, comment);
    269                         else
    270                                 // throw new RuntimeException (e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
    271                                 throw new OsmTransferException (e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
    272                 }
    273                
    274                 catch (Exception e) {
    275                         if (cancel)
    276                                 return false; // assume cancel
    277                         if (e instanceof OsmTransferException)
    278                                 throw (OsmTransferException)e;
    279                         if (e instanceof RuntimeException)
    280                                 throw (RuntimeException)e;
    281                         throw new RuntimeException(e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
    282                 }
    283                 return true;
    284         }
     235                // Look for a detailed error message from the server
     236                retMsg += "\n" + readString(activeConnection.getInputStream());
     237
     238                // Report our error
     239                ByteArrayOutputStream o = new ByteArrayOutputStream();
     240                OsmWriter.output(o, changeset);
     241                System.out.println(new String(o.toByteArray(), "UTF-8").toString());
     242                throw new OsmTransferException (retCode + " " + retMsg);
     243            }
     244        } catch (UnknownHostException e) {
     245            throw new OsmTransferException(tr("Unknown host")+": "+e.getMessage(), e);
     246        } catch(SocketTimeoutException e) {
     247            System.out.println(" timed out, retries left: " + retries);
     248            if (cancel)
     249                return false; // assume cancel
     250            if (retries-- > 0)
     251                startChangeset(retries, comment);
     252            else
     253                throw new OsmTransferException (e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
     254        }
     255        catch (ConnectException e) {
     256            System.out.println(" timed out, retries left: " + retries);
     257            if (cancel)
     258                return false; // assume cancel
     259            if (retries-- > 0)
     260                startChangeset(retries, comment);
     261            else
     262                throw new OsmTransferException (e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
     263        }
     264       
     265        catch (Exception e) {
     266            if (cancel)
     267                return false; // assume cancel
     268            if (e instanceof OsmTransferException)
     269                throw (OsmTransferException)e;
     270            if (e instanceof RuntimeException)
     271                throw (RuntimeException)e;
     272            throw new RuntimeException(e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
     273        }
     274        return true;
     275    }
    285276   
    286277    private void uploadDiff(int retries, Collection<OsmPrimitive> list) throws OsmTransferException {
     
    344335                } else {
    345336                    // Look for a detailed error message from the server
    346                     if (activeConnection.getHeaderField("Error") != null)
    347                         retMsg += "\n" + activeConnection.getHeaderField("Error");
     337                    retMsg += "\n" + readString(activeConnection.getInputStream());
    348338
    349339                    // Report our error
     
    351341                    OsmWriter.output(o, changeset);
    352342                    System.out.println(new String(o.toByteArray(), "UTF-8").toString());
    353                     //throw new RuntimeException(retCode+" "+retMsg);
    354343                    throw new OsmTransferException(retCode+" "+retMsg);
    355344                }
    356345            }
    357346        } catch (UnknownHostException e) {
    358             //throw new RuntimeException(tr("Unknown host")+": "+e.getMessage(), e);
    359347            throw new OsmTransferException(tr("Unknown host")+": "+e.getMessage(), e);
    360348        } catch(SocketTimeoutException e) {
     
    365353                stopChangeset(retries);
    366354            else
    367                 //throw new RuntimeException(e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
    368355                throw new OsmTransferException(e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
    369356        } catch(ConnectException e) {
     
    374361                stopChangeset(retries);
    375362            else
    376                 //throw new RuntimeException(e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
    377363                throw new OsmTransferException(e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
    378364        } catch (Exception e) {
     
    388374   
    389375   
    390         private void stopChangeset(int retries) throws OsmTransferException {
    391                 Main.pleaseWaitDlg.currentAction.setText(tr("Closing changeset..."));
    392                 try {
    393                         if (cancel)
    394                                 return; // assume cancel
    395                         String version = Main.pref.get("osm-server.version", "0.6");
    396                         URL url = new URL(
    397                                         Main.pref.get("osm-server.url") +
    398                                         "/" + version +
    399                                         "/" + "changeset" +
    400                                         "/" + changeset.id +
    401                                         "/close" );
    402                         System.out.print("upload to: "+url+ "..." );
    403                         activeConnection = (HttpURLConnection)url.openConnection();
    404                         activeConnection.setConnectTimeout(15000);
    405                         activeConnection.setRequestMethod("PUT");
    406                         addAuth(activeConnection);
    407                        
    408                         activeConnection.setDoOutput(true);
    409                         OutputStream out = activeConnection.getOutputStream();
    410                         OsmWriter.output(out, changeset);
    411                         out.close();
    412                        
    413                         activeConnection.connect();
    414                         System.out.println("connected");
    415 
    416                         int retCode = activeConnection.getResponseCode();
    417                         if (retCode == 200)
    418                                 changeset.id = readId(activeConnection.getInputStream());
    419                         System.out.println("got return: "+retCode+" with id "+changeset.id);
    420                         String retMsg = activeConnection.getResponseMessage();
    421                         activeConnection.disconnect();
    422                         if (retCode == 404)
    423                         {
    424                                 System.out.println("Server does not support changesets, continuing");
    425                                 return;
    426                         }
    427                         if (retCode != 200 && retCode != 412) {
    428                                 if (retries >= 0) {
    429                                         retries--;
    430                                         System.out.print("backing off for 10 seconds...");
    431                                         Thread.sleep(10000);
    432                                         System.out.println("retrying ("+retries+" left)");
    433                                         stopChangeset(retries);
    434                                 } else {
    435                                         // Look for a detailed error message from the server
    436                                         if (activeConnection.getHeaderField("Error") != null)
    437                                                 retMsg += "\n" + activeConnection.getHeaderField("Error");
    438 
    439                                         // Report our error
    440                                         ByteArrayOutputStream o = new ByteArrayOutputStream();
    441                                         OsmWriter.output(o, changeset);
    442                                         System.out.println(new String(o.toByteArray(), "UTF-8").toString());
    443                                         //throw new RuntimeException(retCode+" "+retMsg);
    444                                         throw new OsmTransferException(retCode+" "+retMsg);
    445                                 }
    446                         }
    447                 } catch (UnknownHostException e) {
    448                         //throw new RuntimeException(tr("Unknown host")+": "+e.getMessage(), e);
    449                         throw new OsmTransferException(tr("Unknown host")+": "+e.getMessage(), e);
    450                 } catch(SocketTimeoutException e) {
    451                         System.out.println(" timed out, retries left: " + retries);
    452                         if (cancel)
    453                                 return; // assume cancel
    454                         if (retries-- > 0)
    455                                 stopChangeset(retries);
    456                         else
    457                                 //throw new RuntimeException(e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
    458                                 throw new OsmTransferException(e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
    459                 } catch(ConnectException e) {
    460                         System.out.println(" timed out, retries left: " + retries);
    461                         if (cancel)
    462                                 return; // assume cancel
    463                         if (retries-- > 0)
    464                                 stopChangeset(retries);
    465                         else
    466                                 //throw new RuntimeException(e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
    467                                 throw new OsmTransferException(e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
    468                 } catch (Exception e) {
    469                         if (cancel)
    470                                 return; // assume cancel
    471                         if (e instanceof OsmTransferException)
    472                                 throw (OsmTransferException)e;
    473                         if (e instanceof RuntimeException)
    474                                 throw (RuntimeException)e;
    475                         throw new RuntimeException(e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
    476                 }
    477         }
    478 
    479         /**
    480          * Upload a single node.
    481          */
    482         public void visit(Node n) {
    483                 if (n.deleted) {
    484                         sendRequest("DELETE", "node", n, true);
    485                 } else {
    486                         sendRequest("PUT", "node", n, true);
    487                 }
    488                 processed.add(n);
    489         }
    490 
    491         /**
    492          * Upload a whole way with the complete node id list.
    493          */
    494         public void visit(Way w) {
    495                 if (w.deleted) {
    496                         sendRequest("DELETE", "way", w, true);
    497                 } else {
    498                         sendRequest("PUT", "way", w, true);
    499                 }
    500                 processed.add(w);
    501         }
    502 
    503         /**
    504          * Upload an relation with all members.
    505          */
    506         public void visit(Relation e) {
    507                 if (e.deleted) {
    508                         sendRequest("DELETE", "relation", e, true);
    509                 } else {
    510                         sendRequest("PUT", "relation", e, true);
    511                 }
    512                 processed.add(e);
    513         }
    514         /**
    515          * Read a long from the input stream and return it.
    516          */
    517         private long readId(InputStream inputStream) throws IOException {
    518                 BufferedReader in = new BufferedReader(new InputStreamReader(
    519                                 inputStream));
    520                 String s = in.readLine();
    521                 if (s == null)
    522                         return 0;
    523                 try {
    524                         return Long.parseLong(s);
    525                 } catch (NumberFormatException e) {
    526                         return 0;
    527                 }
    528         }
    529 
    530         /**
    531          * Send the request. The objects id will be replaced if it was 0 before
    532          * (on add requests).
    533          *
    534          * @param requestMethod The http method used when talking with the server.
    535          * @param urlSuffix The suffix to add at the server url.
    536          * @param osm The primitive to encode to the server.
    537          * @param body the body to be sent
    538          */
    539         private void sendRequestRetry(String requestMethod, String urlSuffix,
    540                         OsmPrimitive osm, OsmWriterInterface body, int retries) throws OsmTransferException {
    541                 try {
    542                         if (cancel)
    543                                 return; // assume cancel
    544                         String version = Main.pref.get("osm-server.version", "0.5");
    545                         URL url = new URL(
    546                                         new URL(Main.pref.get("osm-server.url") +
    547                                         "/" + version + "/"),
    548                                         urlSuffix +
    549                                         "/" + (osm.id==0 ? "create" : osm.id),
    550                                         new MyHttpHandler());
    551                         System.out.print("upload to: "+url+ "..." );
    552                         activeConnection = (HttpURLConnection)url.openConnection();
    553                         activeConnection.setConnectTimeout(15000);
    554                         activeConnection.setRequestMethod(requestMethod);
    555                         addAuth(activeConnection);
    556                         if (body != null) {
    557                                 activeConnection.setDoOutput(true);
    558                                 OutputStream out = activeConnection.getOutputStream();
    559                                 OsmWriter.output(out, body);
    560                                 out.close();
    561                         }
    562                         activeConnection.connect();
    563                         System.out.println("connected");
    564 
    565                         int retCode = activeConnection.getResponseCode();
    566                         /* When creating new, the returned value is the new id, otherwise it is the new version */
    567                         if (retCode == 200)     {
    568                                 if (osm.id == 0) {
    569                                         osm.id = readId(activeConnection.getInputStream());
    570                                         osm.version = 1;
    571                                 } else {
    572                                         int read_version = (int)readId(activeConnection.getInputStream());
    573                                         if (read_version > 0)
    574                                                 osm.version = read_version;
    575                                 }
    576                         } else {
    577                                 System.out.println("got return: "+retCode+" with id "+osm.id);
    578                         }
    579                         activeConnection.disconnect();
    580                         if (retCode == 410 && requestMethod.equals("DELETE"))
    581                                 return; // everything fine.. was already deleted.
    582                         else if (retCode != 200) {
    583                                 if (retries >= 0 && retCode != 412)     {
    584                                         retries--;
    585                                         System.out.print("backing off for 10 seconds...");
    586                                         Thread.sleep(10000);
    587                                         System.out.println("retrying ("+retries+" left)");
    588                                         sendRequestRetry(requestMethod, urlSuffix, osm, body, retries);
    589                                 } else {
    590                                         String retMsg = activeConnection.getResponseMessage();
    591                                         // Look for a detailed error message from the server
    592                                         if (activeConnection.getHeaderField("Error") != null)
    593                                                 retMsg += "\n" + activeConnection.getHeaderField("Error");
    594 
    595                                         // Report our error
    596                                         ByteArrayOutputStream o = new ByteArrayOutputStream();
    597                                         OsmWriter.output(o, body);
    598                                         System.out.println(new String(o.toByteArray(), "UTF-8").toString());
    599                                         //throw new RuntimeException(retCode+" "+retMsg);
    600                                         throw new OsmTransferException(retCode+" "+retMsg);
    601                                 }
    602                         }
    603                 } catch (UnknownHostException e) {
    604                         //throw new RuntimeException(tr("Unknown host")+": "+e.getMessage(), e);
    605                         throw new OsmTransferException(tr("Unknown host")+": "+e.getMessage(), e);
    606                 } catch(SocketTimeoutException e) {
    607                         System.out.println(" timed out, retries left: " + retries);
    608                         if (cancel)
    609                                 return; // assume cancel
    610                         if (retries-- > 0)
    611                                 sendRequestRetry(requestMethod, urlSuffix, osm, body, retries);
    612                         else
    613                                 //throw new RuntimeException (e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
    614                                 throw new OsmTransferException (e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
    615                 } catch(ConnectException e) {
    616                         System.out.println(" timed out, retries left: " + retries);
    617                         if (cancel)
    618                                 return; // assume cancel
    619                         if (retries-- > 0)
    620                                 sendRequestRetry(requestMethod, urlSuffix, osm, body, retries);
    621                         else
    622                                 //throw new RuntimeException (e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
    623                                 throw new OsmTransferException (e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
    624                 } catch (Exception e) {
    625                         if (cancel)
    626                                 return; // assume cancel
    627                         if (e instanceof OsmTransferException)
    628                                 throw (OsmTransferException)e;
    629                         if (e instanceof RuntimeException)
    630                                 throw (RuntimeException)e;
    631                         throw new RuntimeException(e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
    632                 }
    633         }
    634        
    635         private void sendRequest(String requestMethod, String urlSuffix,
    636                         OsmPrimitive osm, boolean addBody)  {
    637                 XmlWriter.OsmWriterInterface body = null;
    638                 if (addBody) {
    639                                 body = new OsmWriter.Single(osm, true, changeset);
    640                 }
    641                 try {
    642                         sendRequestRetry(requestMethod, urlSuffix, osm, body, 10);
    643                 }
    644                 catch (OsmTransferException e) {
    645                         dealWithTransferException (e);
    646                 }
    647         }
    648        
    649         private void dealWithTransferException (OsmTransferException e) {
    650                 Main.pleaseWaitDlg.currentAction.setText(tr("Transfer aborted due to error (will wait now 5 seconds):") + e.getMessage());
    651                 cancel = true;
    652                 try {
    653                         Thread.sleep(5000);
    654                 }
    655                 catch (InterruptedException ex) {}
    656         }
     376    private void stopChangeset(int retries) throws OsmTransferException {
     377        Main.pleaseWaitDlg.currentAction.setText(tr("Closing changeset..."));
     378        try {
     379            if (cancel)
     380                return; // assume cancel
     381            String version = Main.pref.get("osm-server.version", "0.6");
     382            URL url = new URL(
     383                    Main.pref.get("osm-server.url") +
     384                    "/" + version +
     385                    "/" + "changeset" +
     386                    "/" + changeset.id +
     387                    "/close" );
     388            System.out.print("upload to: "+url+ "..." );
     389            activeConnection = (HttpURLConnection)url.openConnection();
     390            activeConnection.setConnectTimeout(15000);
     391            activeConnection.setRequestMethod("PUT");
     392            addAuth(activeConnection);
     393           
     394            activeConnection.setDoOutput(true);
     395            OutputStream out = activeConnection.getOutputStream();
     396            OsmWriter.output(out, changeset);
     397            out.close();
     398           
     399            activeConnection.connect();
     400            System.out.println("connected");
     401
     402            int retCode = activeConnection.getResponseCode();
     403            System.out.println("got return: "+retCode);
     404            String retMsg = activeConnection.getResponseMessage();
     405            activeConnection.disconnect();
     406            if (retCode == 404)    {
     407                System.out.println("Server does not support changesets, or the changeset could not be found, continuing");
     408                return;
     409            }
     410            if (retCode != 200 && retCode != 412) {
     411                if (retries >= 0) {
     412                    retries--;
     413                    System.out.print("backing off for 10 seconds...");
     414                    Thread.sleep(10000);
     415                    System.out.println("retrying ("+retries+" left)");
     416                    stopChangeset(retries);
     417                } else {
     418                    // Look for a detailed error message from the server
     419                    retMsg += readString(activeConnection.getInputStream());
     420                   
     421                    // Report our error
     422                    ByteArrayOutputStream o = new ByteArrayOutputStream();
     423                    OsmWriter.output(o, changeset);
     424                    System.out.println(new String(o.toByteArray(), "UTF-8").toString());
     425                    throw new OsmTransferException(retCode+" "+retMsg);
     426                }
     427            }
     428        } catch (UnknownHostException e) {
     429            throw new OsmTransferException(tr("Unknown host")+": "+e.getMessage(), e);
     430        } catch(SocketTimeoutException e) {
     431            System.out.println(" timed out, retries left: " + retries);
     432            if (cancel)
     433                return; // assume cancel
     434            if (retries-- > 0)
     435                stopChangeset(retries);
     436            else
     437                throw new OsmTransferException(e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
     438        } catch(ConnectException e) {
     439            System.out.println(" timed out, retries left: " + retries);
     440            if (cancel)
     441                return; // assume cancel
     442            if (retries-- > 0)
     443                stopChangeset(retries);
     444            else
     445                throw new OsmTransferException(e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
     446        } catch (Exception e) {
     447            if (cancel)
     448                return; // assume cancel
     449            if (e instanceof OsmTransferException)
     450                throw (OsmTransferException)e;
     451            if (e instanceof RuntimeException)
     452                throw (RuntimeException)e;
     453            throw new RuntimeException(e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
     454        }
     455    }
     456
     457    /**
     458     * Upload a single node.
     459     */
     460    public void visit(Node n) {
     461        if (n.deleted) {
     462            sendRequest("DELETE", "node", n, true);
     463        } else {
     464            sendRequest("PUT", "node", n, true);
     465        }
     466        processed.add(n);
     467    }
     468
     469    /**
     470     * Upload a whole way with the complete node id list.
     471     */
     472    public void visit(Way w) {
     473        if (w.deleted) {
     474            sendRequest("DELETE", "way", w, true);
     475        } else {
     476            sendRequest("PUT", "way", w, true);
     477        }
     478        processed.add(w);
     479    }
     480
     481    /**
     482     * Upload an relation with all members.
     483     */
     484    public void visit(Relation e) {
     485        if (e.deleted) {
     486            sendRequest("DELETE", "relation", e, true);
     487        } else {
     488            sendRequest("PUT", "relation", e, true);
     489        }
     490        processed.add(e);
     491    }
     492   
     493    /**
     494     * Read a long from the input stream and return it.
     495     */
     496    private long readId(InputStream inputStream) throws IOException {
     497        BufferedReader in = new BufferedReader(new InputStreamReader(
     498                inputStream));
     499        String s = in.readLine();
     500        if (s == null)
     501            return 0;
     502        try {
     503            return Long.parseLong(s);
     504        } catch (NumberFormatException e) {
     505            return 0;
     506        }
     507    }
     508
     509    /**
     510     * Consume the input stream and return it as a string.
     511     */
     512    private String readString(InputStream inputStream) throws IOException {
     513        BufferedReader in = new BufferedReader(new InputStreamReader(
     514                inputStream));
     515        StringBuffer sb = new StringBuffer();
     516        String s;
     517        while((s = in.readLine()) != null) {
     518            sb.append(s);
     519            sb.append("\n");
     520        }
     521        return sb.toString();
     522    }
     523
     524    /**
     525     * Send the request. The objects id will be replaced if it was 0 before
     526     * (on add requests).
     527     *
     528     * @param requestMethod The http method used when talking with the server.
     529     * @param urlSuffix The suffix to add at the server url.
     530     * @param osm The primitive to encode to the server.
     531     * @param body the body to be sent
     532     */
     533    private void sendRequestRetry(String requestMethod, String urlSuffix,
     534            OsmPrimitive osm, OsmWriterInterface body, int retries) throws OsmTransferException {
     535        try {
     536            if (cancel)
     537                return; // assume cancel
     538            String version = Main.pref.get("osm-server.version", "0.5");
     539            URL url = new URL(
     540                    new URL(Main.pref.get("osm-server.url") +
     541                    "/" + version + "/"),
     542                    urlSuffix +
     543                    "/" + (osm.id==0 ? "create" : osm.id),
     544                    new MyHttpHandler());
     545            System.out.print("upload to: "+url+ "..." );
     546            activeConnection = (HttpURLConnection)url.openConnection();
     547            activeConnection.setConnectTimeout(15000);
     548            activeConnection.setRequestMethod(requestMethod);
     549            addAuth(activeConnection);
     550            if (body != null) {
     551                activeConnection.setDoOutput(true);
     552                OutputStream out = activeConnection.getOutputStream();
     553                OsmWriter.output(out, body);
     554                out.close();
     555            }
     556            activeConnection.connect();
     557            System.out.println("connected");
     558
     559            int retCode = activeConnection.getResponseCode();
     560            /* When creating new, the returned value is the new id, otherwise it is the new version */
     561            if (retCode == 200)    {
     562                if (osm.id == 0) {
     563                    osm.id = readId(activeConnection.getInputStream());
     564                    osm.version = 1;
     565                } else {
     566                    int read_version = (int)readId(activeConnection.getInputStream());
     567                    if (read_version > 0)
     568                        osm.version = read_version;
     569                }
     570            } else {
     571                System.out.println("got return: "+retCode+" with id "+osm.id);
     572            }
     573            activeConnection.disconnect();
     574            if (retCode == 410 && requestMethod.equals("DELETE"))
     575                return; // everything fine.. was already deleted.
     576            else if (retCode != 200) {
     577                if (retries >= 0 && retCode != 412)    {
     578                    retries--;
     579                    System.out.print("backing off for 10 seconds...");
     580                    Thread.sleep(10000);
     581                    System.out.println("retrying ("+retries+" left)");
     582                    sendRequestRetry(requestMethod, urlSuffix, osm, body, retries);
     583                } else {
     584                    String retMsg = activeConnection.getResponseMessage();
     585                    // Look for a detailed error message from the server
     586                    if (activeConnection.getHeaderField("Error") != null)
     587                        retMsg += "\n" + activeConnection.getHeaderField("Error");
     588
     589                    // Report our error
     590                    ByteArrayOutputStream o = new ByteArrayOutputStream();
     591                    OsmWriter.output(o, body);
     592                    System.out.println(new String(o.toByteArray(), "UTF-8").toString());
     593                    throw new OsmTransferException(retCode+" "+retMsg);
     594                }
     595            }
     596        } catch (UnknownHostException e) {
     597            throw new OsmTransferException(tr("Unknown host")+": "+e.getMessage(), e);
     598        } catch(SocketTimeoutException e) {
     599            System.out.println(" timed out, retries left: " + retries);
     600            if (cancel)
     601                return; // assume cancel
     602            if (retries-- > 0)
     603                sendRequestRetry(requestMethod, urlSuffix, osm, body, retries);
     604            else
     605                throw new OsmTransferException (e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
     606        } catch(ConnectException e) {
     607            System.out.println(" timed out, retries left: " + retries);
     608            if (cancel)
     609                return; // assume cancel
     610            if (retries-- > 0)
     611                sendRequestRetry(requestMethod, urlSuffix, osm, body, retries);
     612            else
     613                throw new OsmTransferException (e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
     614        } catch (Exception e) {
     615            if (cancel)
     616                return; // assume cancel
     617            if (e instanceof OsmTransferException)
     618                throw (OsmTransferException)e;
     619            if (e instanceof RuntimeException)
     620                throw (RuntimeException)e;
     621            throw new RuntimeException(e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
     622        }
     623    }
     624   
     625    private void sendRequest(String requestMethod, String urlSuffix,
     626            OsmPrimitive osm, boolean addBody)  {
     627        XmlWriter.OsmWriterInterface body = null;
     628        if (addBody) {
     629                body = new OsmWriter.Single(osm, true, changeset);
     630        }
     631        try {
     632            sendRequestRetry(requestMethod, urlSuffix, osm, body, 10);
     633        }
     634        catch (OsmTransferException e) {
     635            dealWithTransferException (e);
     636        }
     637    }
     638   
     639    private void dealWithTransferException (OsmTransferException e) {
     640        Main.pleaseWaitDlg.currentAction.setText(tr("Transfer aborted due to error (will wait for 5 seconds):") + e.getMessage());
     641        cancel = true;
     642        try {
     643            Thread.sleep(5000);
     644        }
     645        catch (InterruptedException ex) {}
     646    }
    657647}
Note: See TracChangeset for help on using the changeset viewer.