Changeset 1670 in josm


Ignore:
Timestamp:
15.06.2009 20:22:46 (3 years ago)
Author:
Gubaer
Message:

fixed: bug in OsmApi.getOsmApi()
cleanup: exception handling in interfacing with OSM API
new: new action for updating individual elements with the their current state on the server (including new menu item in the file menu)
new: improved user feedback in case of conflicts
new: handles 410 Gone conflicts when uploading a changeset
new: undoable command for "purging" a primitive from the current dataset (necessary if the primitive is already deleted on the server and the user wants to remove it from its local dataset)
new: undoable command for "undeleting" an already deleted primitive on the server (kind of "cloning")
new: after a full upload, checks whether there are primitives in the local dataset which might be deleted on the server.
new: data structures for history data
new: history download support in io package

Location:
trunk
Files:
20 added
23 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/actions/UpdateDataAction.java

    r1465 r1670  
    1515import org.openstreetmap.josm.actions.downloadtasks.DownloadOsmTaskList; 
    1616import org.openstreetmap.josm.data.osm.DataSource; 
    17 import org.openstreetmap.josm.gui.ExtendedDialog; 
    1817import org.openstreetmap.josm.tools.Shortcut; 
    1918 
     
    2625                        tr("Update Data"), 
    2726                        KeyEvent.VK_U, 
    28                         Shortcut.GROUP_NONE), 
    29                 true); 
     27                        Shortcut.GROUP_HOTKEY), 
     28                        true); 
    3029    } 
    3130 
     
    3332        int bboxCount = 0; 
    3433        List<Area> areas = new ArrayList<Area>(); 
    35         for(DataSource ds : Main.main.editLayer().data.dataSources) 
     34        for(DataSource ds : Main.main.editLayer().data.dataSources) { 
    3635            areas.add(new Area(ds.bounds.asRect())); 
    37  
    38         // This would loop over all DataLayers but download all data to the currently 
    39         // selected one 
    40         /*for(Layer l : Main.map.mapView.getAllLayers()) { 
    41             if(!(l instanceof OsmDataLayer)) continue; 
    42  
    43             for(DataSource ds : ((OsmDataLayer)l).data.dataSources) 
    44                 areas.add(new Area(ds.bounds.asRect())); 
    45         }*/ 
     36        } 
    4637 
    4738        // The next two blocks removes every intersection from every DataSource Area 
     
    6253 
    6354        for(Area a : areas) { 
    64             if(a.isEmpty()) 
     55            if(a.isEmpty()) { 
    6556                continue; 
     57            } 
    6658            bboxCount++; 
    6759        } 
     
    6961        if(bboxCount == 0) { 
    7062            JOptionPane.showMessageDialog(Main.parent, 
    71                         tr("No data to update found. Have you already opened or downloaded a data layer?")); 
    72                 return; 
     63                    tr("No data to update found. Have you already opened or downloaded a data layer?")); 
     64            return; 
    7365        } 
    74  
    75         int result = new ExtendedDialog(Main.parent, 
    76                 tr("Update Data"), 
    77                 tr("This action will require {0} individual download requests. " 
    78                         + "Do you wish to continue?", bboxCount), 
    79                 new String[] { tr("Update Data"), tr("Cancel") }, 
    80                 new String[] { "updatedata.png", "cancel.png" }).getValue(); 
    81  
    82         if(result != 1) 
    83             return; 
    8466 
    8567        new DownloadOsmTaskList().download(false, areas); 
    8668    } 
    87  
    8869} 
  • trunk/src/org/openstreetmap/josm/actions/UploadAction.java

    r1668 r1670  
    44import static org.openstreetmap.josm.tools.I18n.tr; 
    55 
    6 import java.awt.EventQueue; 
    76import java.awt.GridBagLayout; 
    87import java.awt.event.ActionEvent; 
     
    1312import java.util.LinkedList; 
    1413import java.util.List; 
    15 import java.util.concurrent.ExecutionException; 
    16 import java.util.concurrent.FutureTask; 
     14import java.util.logging.Logger; 
    1715import java.util.regex.Matcher; 
    1816import java.util.regex.Pattern; 
     
    2321import javax.swing.JPanel; 
    2422import javax.swing.JScrollPane; 
    25 import javax.swing.SwingUtilities; 
    2623 
    2724import org.openstreetmap.josm.Main; 
    2825import org.openstreetmap.josm.data.osm.OsmPrimitive; 
    29 import org.openstreetmap.josm.data.osm.visitor.CreateOsmChangeVisitor; 
    3026import org.openstreetmap.josm.gui.ExtendedDialog; 
    3127import org.openstreetmap.josm.gui.OsmPrimitivRenderer; 
    3228import org.openstreetmap.josm.gui.PleaseWaitRunnable; 
    3329import org.openstreetmap.josm.gui.historycombobox.SuggestingJHistoryComboBox; 
    34 import org.openstreetmap.josm.io.DiffResultReader; 
    3530import org.openstreetmap.josm.io.OsmApi; 
    3631import org.openstreetmap.josm.io.OsmApiException; 
     
    4742 * An dialog is displayed asking the user to specify a rectangle to grab. 
    4843 * The url and account settings from the preferences are used. 
     44 *  
     45 * If the upload fails this action offers various options to resolve conflicts. 
    4946 * 
    5047 * @author imi 
    5148 */ 
    5249public class UploadAction extends JosmAction { 
     50    static private Logger logger = Logger.getLogger(UploadAction.class.getName()); 
    5351 
    5452    public static final String HISTORY_KEY = "upload.comment.history"; 
     
    215213                        return; 
    216214                    } 
    217                     System.out.println("got exception: " + sxe.toString()); 
    218215                    uploadFailed = true; 
    219216                    lastException = sxe; 
     
    230227                server.disconnectActiveConnection(); 
    231228                uploadCancelled = true; 
    232             }; 
    233  
    234         } 
     229            } 
     230        } 
     231 
    235232        Main.worker.execute(new UploadDiffTask()); 
    236233    } 
    237234 
    238     public void handleFailedUpload(Exception e) { 
     235    /** 
     236     * Synchronizes the local state of an {@see OsmPrimitive} with its state on the 
     237     * server. The method uses an individual GET for the primitive. 
     238     *  
     239     * @param id the primitive ID 
     240     */ 
     241    protected void synchronizePrimitive(final String id) { 
     242 
     243        /** 
     244         * The asynchronous task to update a a specific id 
     245         * 
     246         */ 
     247        class UpdatePrimitiveTask extends  PleaseWaitRunnable { 
     248 
     249            private boolean uploadCancelled = false; 
     250            private boolean uploadFailed = false; 
     251            private Exception lastException = null; 
     252 
     253            public UpdatePrimitiveTask() { 
     254                super(tr("Updating primitive"),false /* don't ignore exceptions */); 
     255            } 
     256 
     257            @Override protected void realRun() throws SAXException, IOException { 
     258                try { 
     259                    UpdateSelectionAction act = new UpdateSelectionAction(); 
     260                    act.updatePrimitive(Long.parseLong(id)); 
     261                } catch (Exception sxe) { 
     262                    if (uploadCancelled) { 
     263                        System.out.println("Ignoring exception caught because upload is cancelled. Exception is: " + sxe.toString()); 
     264                        return; 
     265                    } 
     266                    uploadFailed = true; 
     267                    lastException = sxe; 
     268                } 
     269            } 
     270 
     271            @Override protected void finish() { 
     272                if (uploadFailed) { 
     273                    handleFailedUpload(lastException); 
     274                } 
     275            } 
     276 
     277            @Override protected void cancel() { 
     278                OsmApi.getOsmApi().cancel(); 
     279                uploadCancelled = true; 
     280            } 
     281        } 
     282 
     283        Main.worker.execute(new UpdatePrimitiveTask()); 
     284    } 
     285 
     286    /** 
     287     * Synchronizes the local state of the dataset with the state on the server. 
     288     *  
     289     * Reuses the functionality of {@see UpdateDataAction}. 
     290     *  
     291     * @see UpdateDataAction#actionPerformed(ActionEvent) 
     292     */ 
     293    protected void synchronizeDataSet() { 
     294        UpdateDataAction act = new UpdateDataAction(); 
     295        act.actionPerformed(new ActionEvent(this,0,"")); 
     296    } 
     297 
     298    /** 
     299     * Handles the case that a conflict in a specific {@see OsmPrimitive} was detected while 
     300     * uploading 
     301     *  
     302     * @param primitiveType  the type of the primitive, either <code>node</code>, <code>way</code> or 
     303     *    <code>relation</code> 
     304     * @param id  the id of the primitive 
     305     * @param serverVersion  the version of the primitive on the server 
     306     * @param myVersion  the version of the primitive in the local dataset 
     307     */ 
     308    protected void handleUploadConflictForKnownConflict(String primitiveType, String id, String serverVersion, String myVersion) { 
     309        Object[] options = new Object[] { 
     310                tr("Synchronize {0} {1} only", tr(primitiveType), id), 
     311                tr("Synchronize entire dataset"), 
     312                tr("Cancel") 
     313        }; 
     314        Object defaultOption = options[0]; 
     315        String msg =  tr("<html>Uploading <strong>failed</strong> because the server has a newer version of one<br>" 
     316                + "of your nodes, ways, or relations.<br>" 
     317                + "The conflict is caused by the <strong>{0}</strong> with id <strong>{1}</strong>,<br>" 
     318                + "the server has version {2}, your version is {3}.<br>" 
     319                + "<br>" 
     320                + "Click <strong>{4}</strong> to synchronize the conflicting primitive only.<br>" 
     321                + "Click <strong>{5}</strong> to synchronize the entire local dataset with the server.<br>" 
     322                + "Click <strong>{6}</strong> to abort and continue editing.<br></html>", 
     323                tr(primitiveType), id, serverVersion, myVersion, 
     324                options[0], options[1], options[2] 
     325        ); 
     326        int optionsType = JOptionPane.YES_NO_CANCEL_OPTION; 
     327        int ret = JOptionPane.showOptionDialog( 
     328                null, 
     329                msg, 
     330                tr("Conflict detected"), 
     331                optionsType, 
     332                JOptionPane.ERROR_MESSAGE, 
     333                null, 
     334                options, 
     335                defaultOption 
     336        ); 
     337        switch(ret) { 
     338        case JOptionPane.CLOSED_OPTION: return; 
     339        case JOptionPane.CANCEL_OPTION: return; 
     340        case 0: synchronizePrimitive(id); break; 
     341        case 1: synchronizeDataSet(); break; 
     342        default: 
     343            // should not happen 
     344            throw new IllegalStateException(tr("unexpected return value. Got {0}", ret)); 
     345        } 
     346    } 
     347 
     348    /** 
     349     * Handles the case that a conflict was detected while uploading where we don't 
     350     * know what {@see OsmPrimitive} actually caused the conflict (for whatever reason) 
     351     *  
     352     */ 
     353    protected void handleUploadConflictForUnknownConflict() { 
     354        Object[] options = new Object[] { 
     355                tr("Synchronize entire dataset"), 
     356                tr("Cancel") 
     357        }; 
     358        Object defaultOption = options[0]; 
     359        String msg =  tr("<html>Uploading <strong>failed</strong> because the server has a newer version of one<br>" 
     360                + "of your nodes, ways, or relations.<br>" 
     361                + "<br>" 
     362                + "Click <strong>{0}</strong> to synchronize the entire local dataset with the server.<br>" 
     363                + "Click <strong>{1}</strong> to abort and continue editing.<br></html>", 
     364                options[0], options[1] 
     365        ); 
     366        int optionsType = JOptionPane.YES_NO_OPTION; 
     367        int ret = JOptionPane.showOptionDialog( 
     368                null, 
     369                msg, 
     370                tr("Conflict detected"), 
     371                optionsType, 
     372                JOptionPane.ERROR_MESSAGE, 
     373                null, 
     374                options, 
     375                defaultOption 
     376        ); 
     377        switch(ret) { 
     378        case JOptionPane.CLOSED_OPTION: return; 
     379        case 1: return; 
     380        case 0: synchronizeDataSet(); break; 
     381        default: 
     382            // should not happen 
     383            throw new IllegalStateException(tr("unexpected return value. Got {0}", ret)); 
     384        } 
     385    } 
     386 
     387    /** 
     388     * handles an upload conflict, i.e. an error indicated by a HTTP return code 409. 
     389     *  
     390     * @param e  the exception 
     391     */ 
     392    protected void handleUploadConflict(OsmApiException e) { 
     393        String pattern = "Version mismatch: Provided (\\d+), server had: (\\d+) of (\\S+) (\\d+)"; 
     394        Pattern p = Pattern.compile(pattern); 
     395        Matcher m = p.matcher(e.getErrorHeader()); 
     396        if (m.matches()) { 
     397            handleUploadConflictForKnownConflict(m.group(3), m.group(4), m.group(2),m.group(1)); 
     398        } else { 
     399            logger.warning(tr("Warning: error header \"{0}\" did not match expected pattern \"{1}\"", e.getErrorHeader(),pattern)); 
     400            handleUploadConflictForUnknownConflict(); 
     401        } 
     402    } 
     403 
     404    /** 
     405     * Handles an upload error due to a violated precondition, i.e. a HTTP return code 412 
     406     *  
     407     * @param e the exception 
     408     */ 
     409    protected void handlePreconditionFailed(OsmApiException e) { 
     410        JOptionPane.showMessageDialog( 
     411                Main.parent, 
     412                tr("<html>Uploading to the server <strong>failed</strong> because your current<br>" 
     413                        +"dataset violates a precondition.<br>" 
     414                        +"The error message is:<br>" 
     415                        + "{0}" 
     416                        + "</html>", 
     417                        e.getMessage() 
     418                ), 
     419                tr("Precondition violation"), 
     420                JOptionPane.ERROR_MESSAGE 
     421        ); 
     422        e.printStackTrace(); 
     423    } 
     424 
     425 
     426    /** 
     427     * Handles an error due to a delete request on an already deleted 
     428     * {@see OsmPrimitive}, i.e. a HTTP response code 410, where we know what 
     429     * {@see OsmPrimitive} is responsible for the error. 
     430     *  
     431     *  Reuses functionality of the {@see UpdateSelectionAction} to resolve 
     432     *  conflicts due to mismatches in the deleted state. 
     433     *  
     434     * @param primitiveType the type of the primitive 
     435     * @param id the id of the primitive 
     436     *  
     437     * @see UpdateSelectionAction#handlePrimitiveGoneException(long) 
     438     */ 
     439    protected void handleGoneForKnownPrimitive(String primitiveType, String id) { 
     440        UpdateSelectionAction act = new UpdateSelectionAction(); 
     441        act.handlePrimitiveGoneException(Long.parseLong(id)); 
     442    } 
     443 
     444    /** 
     445     * handles the case of an error due to a delete request on an already deleted 
     446     * {@see OsmPrimitive}, i.e. a HTTP response code 410, where we don't know which 
     447     * {@see OsmPrimitive} is causing the error. 
     448     *  
     449     * @param e the exception 
     450     */ 
     451    protected void handleGoneForUnknownPrimitive(OsmApiException e) { 
     452        String msg =  tr("<html>Uploading <strong>failed</strong> because a primitive you tried to<br>" 
     453                + "delete on the server is already deleted.<br>" 
     454                + "<br>" 
     455                + "The error message is:<br>" 
     456                + "{0}" 
     457                + "</html>", 
     458                e.getMessage() 
     459        ); 
     460        JOptionPane.showMessageDialog( 
     461                Main.parent, 
     462                msg, 
     463                tr("Primitive already deleted"), 
     464                JOptionPane.ERROR_MESSAGE 
     465        ); 
     466 
     467    } 
     468 
     469    /** 
     470     * Handles an error which is caused by a delete request for an already deleted 
     471     * {@see OsmPrimitive} on the server, i.e. a HTTP response code of 410. 
     472     * Note that an <strong>update</strong> on an already deleted object results 
     473     * in a 409, not a 410. 
     474     *  
     475     * @param e the exception 
     476     */ 
     477    protected void handleGone(OsmApiException e) { 
     478        String pattern = "The (\\S+) with the id (\\d+) has already been deleted"; 
     479        Pattern p = Pattern.compile(pattern); 
     480        Matcher m = p.matcher(e.getErrorHeader()); 
     481        if (m.matches()) { 
     482            handleGoneForKnownPrimitive(m.group(1), m.group(2)); 
     483        } else { 
     484            logger.warning(tr("Error header \"{0}\" doesn't match expected pattern \"{1}\"",e.getErrorHeader(), pattern)); 
     485            handleGoneForUnknownPrimitive(e); 
     486        } 
     487    } 
     488 
     489 
     490    /** 
     491     * error handler for any exception thrown during upload 
     492     *  
     493     * @param e the exception 
     494     */ 
     495    protected void handleFailedUpload(Exception e) { 
     496        // API initialization failed. Notify the user and return. 
     497        // 
    239498        if (e instanceof OsmApiInitializationException) { 
    240             handleOsmApiInitializationException(e); 
     499            handleOsmApiInitializationException((OsmApiInitializationException)e); 
    241500            return; 
    242501        } 
     502 
    243503        if (e instanceof OsmApiException) { 
    244504            OsmApiException ex = (OsmApiException)e; 
     505            // There was an upload conflict. Let the user decide whether 
     506            // and how to resolve it 
     507            // 
    245508            if(ex.getResponseCode() == HttpURLConnection.HTTP_CONFLICT) { 
    246                 Pattern p = Pattern.compile("Version mismatch: Provided (\\d+), server had: (\\d+) of (\\S+) (\\d+)"); 
    247                 Matcher m = p.matcher(ex.getErrorHeader()); 
    248                 String msg; 
    249                 if (m.matches()) { 
    250                     msg =  tr("<html>Uploading <strong>failed</strong> because the server has a newer version of one<br>" 
    251                             + "of your nodes, ways or relations.<br>" 
    252                             + "The conflict is caused by the <strong>{0}</strong> with id <strong>{1}</strong>,<br>" 
    253                             + "the server has version {2}, your version is {3}.<br>" 
    254                             + "Please synchronize your local dataset using <br>" 
    255                             + "<strong>File-&gt;Update Data</strong>, resolve<br>" 
    256                             + "any conflicts and try to upload again.</html>", 
    257                             m.group(3),m.group(4), m.group(2), m.group(1) 
    258                     ); 
    259                 } else { 
    260                     msg =  tr("<html>Uploading failed because the server has a newer version of one<br>" 
    261                             + "of your nodes, ways or relations.<br>" 
    262                             + "Please synchronize your local dataset using <br>" 
    263                             + "<strong>File-&gt;Update Data</strong>, resolve<br>" 
    264                             + "any conflicts and try to upload again.</html>" 
    265                     ); 
    266                 } 
    267                 JOptionPane.showMessageDialog( 
    268                         null, 
    269                         msg, 
    270                         tr("Upload to OSM API failed"), 
    271                         JOptionPane.WARNING_MESSAGE 
    272                 ); 
     509                handleUploadConflict(ex); 
    273510                return; 
    274511            } 
    275         } 
     512            // There was a precondition failed. Notify the user. 
     513            // 
     514            else if (ex.getResponseCode() == HttpURLConnection.HTTP_PRECON_FAILED) { 
     515                handlePreconditionFailed(ex); 
     516                return; 
     517            } 
     518            // Tried to delete an already deleted primitive? Let the user 
     519            // decide whether and how to resolve this conflict. 
     520            // 
     521            else if (ex.getResponseCode() == HttpURLConnection.HTTP_GONE) { 
     522                handleGone(ex); 
     523                return; 
     524            } 
     525        } 
     526 
     527        // For any other exception just notify the user 
     528        // 
     529        String msg = e.getMessage().substring(0,Math.min(80, e.getMessage().length())); 
     530        if (msg.length() < e.getMessage().length()) { 
     531            msg += " ..."; 
     532        } 
     533        e.printStackTrace(); 
    276534        JOptionPane.showMessageDialog( 
    277535                null, 
    278                 e.getMessage(), 
     536                msg, 
    279537                tr("Upload to OSM API failed"), 
    280538                JOptionPane.ERROR_MESSAGE 
    281539        ); 
    282     } 
    283  
    284     protected void handleOsmApiInitializationException(Exception e) { 
     540 
     541    } 
     542 
     543    /** 
     544     * handles an exception caught during OSM API initialization 
     545     *  
     546     * @param e the exception 
     547     */ 
     548    protected void handleOsmApiInitializationException(OsmApiInitializationException e) { 
    285549        JOptionPane.showMessageDialog( 
    286                 null, 
     550                Main.parent, 
    287551                tr(   "Failed to initialize communication with the OSM server {0}.\n" 
    288552                        + "Check the server URL in your preferences and your internet connection.", 
  • trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java

    r1647 r1670  
    2222import org.openstreetmap.josm.io.OsmServerLocationReader; 
    2323import org.openstreetmap.josm.io.OsmServerReader; 
     24import org.openstreetmap.josm.io.OsmTransferException; 
    2425import org.xml.sax.SAXException; 
    2526 
     
    3233    private static Bounds currentBounds; 
    3334    private Future<Task> task = null; 
     35    private DataSet downloadedData; 
    3436 
    35     private static class Task extends PleaseWaitRunnable { 
     37    private class Task extends PleaseWaitRunnable { 
    3638        private OsmServerReader reader; 
    3739        private DataSet dataSet; 
     
    4951        } 
    5052 
    51         @Override public void realRun() throws IOException, SAXException { 
     53        @Override public void realRun() throws IOException, SAXException, OsmTransferException { 
    5254            Main.pleaseWaitDlg.setCustomText(msg); 
    5355            dataSet = reader.parseOsm(); 
     
    5961            if (dataSet.allPrimitives().isEmpty()) { 
    6062                // If silent is set to true, we don't want to see information messages 
    61                 if(!silent) 
     63                if(!silent) { 
    6264                    errorMessage = tr("No data imported."); 
     65                } 
    6366                // need to synthesize a download bounds lest the visual indication of downloaded 
    6467                // area doesn't work 
    6568                dataSet.dataSources.add(new DataSource(currentBounds, "OpenStreetMap server")); 
    6669            } 
    67  
     70            rememberDownloadedData(dataSet); 
    6871            OsmDataLayer layer = new OsmDataLayer(dataSet, tr("Data Layer {0}", num), null); 
    69             if (newLayer) 
     72            if (newLayer) { 
    7073                Main.main.addLayer(layer); 
    71             else 
     74            } else { 
    7275                Main.main.editLayer().mergeFrom(layer); 
     76            } 
    7377 
    7478            Main.pleaseWaitDlg.setCustomText(""); 
     
    7680 
    7781        @Override protected void cancel() { 
    78             if (reader != null) 
     82            if (reader != null) { 
    7983                reader.cancel(); 
     84            } 
    8085            Main.pleaseWaitDlg.cancel.setEnabled(false); 
    8186        } 
    8287    } 
    8388    private JCheckBox checkBox = new JCheckBox(tr("OpenStreetMap data"), true); 
     89 
     90    private void rememberDownloadedData(DataSet ds) { 
     91        this.downloadedData = ds; 
     92    } 
     93 
     94    public DataSet getDownloadedData() { 
     95        return downloadedData; 
     96    } 
    8497 
    8598    public void download(DownloadAction action, double minlat, double minlon, 
     
    96109 
    97110        boolean newLayer = action != null 
    98                                 && (action.dialog == null || action.dialog.newLayer.isSelected()); 
     111        && (action.dialog == null || action.dialog.newLayer.isSelected()); 
    99112 
    100113        Task t = new Task(newLayer, 
     
    124137                false, 
    125138                getDataLayersCount(), 
    126                 ""); 
     139        ""); 
    127140        task = Main.worker.submit(t, t); 
    128141    } 
     
    145158        int num = 0; 
    146159        for(Layer l : Main.map.mapView.getAllLayers()) 
    147             if(l instanceof OsmDataLayer) 
     160            if(l instanceof OsmDataLayer) { 
    148161                num++; 
     162            } 
    149163        return num; 
    150164    } 
    151165 
    152    /* 
    153     * (non-Javadoc) 
    154     * @see org.openstreetmap.josm.gui.download.DownloadDialog.DownloadTask#getErrorMessage() 
    155     */ 
     166    /* 
     167     * (non-Javadoc) 
     168     * @see org.openstreetmap.josm.gui.download.DownloadDialog.DownloadTask#getErrorMessage() 
     169     */ 
    156170    public String getErrorMessage() { 
    157171        if(task == null) 
     
    161175            Task t = task.get(); 
    162176            return t.errorMessage == null 
    163                 ? "" 
    164                 : t.errorMessage; 
     177            ? "" 
     178                    : t.errorMessage; 
    165179        } catch (Exception e) { 
    166180            return ""; 
  • trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTaskList.java

    r1465 r1670  
    44import static org.openstreetmap.josm.tools.I18n.tr; 
    55 
     6import java.awt.EventQueue; 
     7import java.awt.event.ActionEvent; 
    68import java.awt.geom.Area; 
    79import java.awt.geom.Rectangle2D; 
     10import java.util.ArrayList; 
    811import java.util.Collection; 
     12import java.util.HashSet; 
    913import java.util.LinkedList; 
    1014import java.util.List; 
     15import java.util.Set; 
    1116 
    1217import javax.swing.JOptionPane; 
    1318 
    1419import org.openstreetmap.josm.Main; 
     20import org.openstreetmap.josm.actions.UpdateSelectionAction; 
    1521import org.openstreetmap.josm.data.osm.DataSet; 
     22import org.openstreetmap.josm.data.osm.OsmPrimitive; 
     23import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 
    1624import org.openstreetmap.josm.gui.download.DownloadDialog.DownloadTask; 
    1725import org.openstreetmap.josm.gui.layer.Layer; 
     
    6270    public void download(boolean newLayer, Collection<Area> areas) { 
    6371        List<Rectangle2D> rects = new LinkedList<Rectangle2D>(); 
    64         for(Area a : areas) 
     72        for(Area a : areas) { 
    6573            rects.add(a.getBounds2D()); 
     74        } 
    6675 
    6776        download(newLayer, rects); 
     
    7685        for(DownloadTask dt : osmTasks) { 
    7786            String err = dt.getErrorMessage(); 
    78             if(err.equals("")) 
     87            if(err.equals("")) { 
    7988                continue; 
     89            } 
    8090            errors += "* " + err + "\r\n"; 
    8191        } 
    8292 
    83         osmTasks.clear(); 
    84         if(errors.equals("")) 
     93        if(! errors.equals("")) { 
     94            JOptionPane.showMessageDialog(Main.parent, 
     95                    tr("The following errors occured during mass download:") + "\r\n" + errors, 
     96                    tr("Errors during Download"), 
     97                    JOptionPane.ERROR_MESSAGE); 
    8598            return; 
     99        } 
    86100 
    87         JOptionPane.showMessageDialog(Main.parent, 
    88                 tr("The following errors occured during mass download:") + "\r\n" + errors, 
    89                 tr("Errors during Download"), 
    90                 JOptionPane.ERROR_MESSAGE); 
     101        Set<Long> myPrimitiveIds = Main.main.editLayer().data.getPrimitiveIds(); 
     102        Set<Long> downloadedIds = getDownloadedIds(); 
     103        myPrimitiveIds.removeAll(downloadedIds); 
     104        if (! myPrimitiveIds.isEmpty()) { 
     105            handlePotentiallyDeletedPrimitives(myPrimitiveIds); 
     106        } 
     107    } 
     108 
     109    protected void checkPotentiallyDeletedPrimitives(Set<Long> potentiallyDeleted) { 
     110        DataSet ds =  Main.main.editLayer().data; 
     111        ArrayList<OsmPrimitive> toSelect = new ArrayList<OsmPrimitive>(); 
     112        for (Long id : potentiallyDeleted) { 
     113            OsmPrimitive primitive = ds.getPrimitiveById(id); 
     114            if (primitive != null) { 
     115                toSelect.add(primitive); 
     116            } 
     117        } 
     118        ds.setSelected(toSelect); 
     119        EventQueue.invokeLater( 
     120                new Runnable() { 
     121                    public void run() { 
     122                        new UpdateSelectionAction().actionPerformed(new ActionEvent(this, 0, "")); 
     123                    } 
     124                } 
     125        ); 
     126    } 
     127 
     128    protected void handlePotentiallyDeletedPrimitives(Set<Long> potentiallyDeleted) { 
     129        String [] options = { 
     130                "Check individually", 
     131                "Ignore" 
     132        }; 
     133 
     134        String message = tr("<html>" 
     135                +  "There are {0} primitives in your local dataset which<br>" 
     136                + "might be deleted on the server. If you later try to delete or<br>" 
     137                + "update them on the server the server is likely to report a<br>" 
     138                + "conflict.<br>" 
     139                + "<br>" 
     140                + "Click <strong>{1}</strong> to check these primitives individually.<br>" 
     141                + "Click <strong>{2}</strong> to ignore.<br>" 
     142                + "</html>", 
     143                potentiallyDeleted.size(), options[0], options[1] 
     144        ); 
     145 
     146        int ret = JOptionPane.showOptionDialog( 
     147                Main.parent, 
     148                message, 
     149                tr("Deleted or moved primitives"), 
     150                JOptionPane.YES_NO_OPTION, 
     151                JOptionPane.WARNING_MESSAGE, 
     152                null, 
     153                options, 
     154                options[0] 
     155        ); 
     156        switch(ret) { 
     157        case JOptionPane.CLOSED_OPTION: return; 
     158        case JOptionPane.NO_OPTION: return; 
     159        case JOptionPane.YES_OPTION: checkPotentiallyDeletedPrimitives(potentiallyDeleted); break; 
     160        } 
     161    } 
     162 
     163    protected boolean wasDownloaded(long id, DataSet ds) { 
     164        OsmPrimitive primitive = ds.getPrimitiveById(id); 
     165        return primitive != null; 
     166    } 
     167 
     168    public boolean wasDownloaded(long id) { 
     169        for (DownloadTask task : osmTasks) { 
     170            if(task instanceof DownloadOsmTask) { 
     171                DataSet ds = ((DownloadOsmTask)task).getDownloadedData(); 
     172                if(wasDownloaded(id,ds)) return true; 
     173            } 
     174        } 
     175        return false; 
     176    } 
     177 
     178 
     179    public Set<Long> getDownloadedIds() { 
     180        HashSet<Long> ret = new HashSet<Long>(); 
     181        for (DownloadTask task : osmTasks) { 
     182            if(task instanceof DownloadOsmTask) { 
     183                DataSet ds = ((DownloadOsmTask)task).getDownloadedData(); 
     184                ret.addAll(ds.getPrimitiveIds()); 
     185            } 
     186        } 
     187        return ret; 
    91188    } 
    92189} 
  • trunk/src/org/openstreetmap/josm/actions/search/SelectionWebsiteLoader.java

    r1195 r1670  
    2222import org.openstreetmap.josm.gui.PleaseWaitRunnable; 
    2323import org.openstreetmap.josm.io.OsmIdReader; 
     24import org.openstreetmap.josm.io.OsmTransferException; 
    2425import org.openstreetmap.josm.io.ProgressInputStream; 
    2526import org.xml.sax.SAXException; 
     
    4748            for (OsmPrimitive osm : Main.ds.allNonDeletedPrimitives()) { 
    4849                if (ids.containsKey(osm.id) && osm.getClass().getName().toLowerCase().endsWith(ids.get(osm.id))) { 
    49                     if (mode == SearchAction.SearchMode.remove) 
     50                    if (mode == SearchAction.SearchMode.remove) { 
    5051                        sel.remove(osm); 
    51                     else 
     52                    } else { 
    5253                        sel.add(osm); 
     54                    } 
    5355                } 
    5456            } 
     
    5961            e.printStackTrace(); 
    6062            JOptionPane.showMessageDialog(Main.parent,tr("Parsing error in URL: \"{0}\"",url)); 
     63        } catch(OsmTransferException e) { 
     64            e.printStackTrace(); 
     65            if (e.getCause() != null) { 
     66                if (e.getCause() instanceof IOException ) { 
     67                    JOptionPane.showMessageDialog(Main.parent, tr("Could not read from URL: \"{0}\"",url), 
     68                            tr("Error"), JOptionPane.ERROR_MESSAGE); 
     69                } else if (e.getCause() instanceof SAXException) { 
     70                    JOptionPane.showMessageDialog(Main.parent,tr("Parsing error in URL: \"{0}\"",url), 
     71                            tr("Error"), JOptionPane.ERROR_MESSAGE); 
     72                } 
     73            } else { 
     74                JOptionPane.showMessageDialog(Main.parent,tr("Error while communicating with server.",url), 
     75                        tr("Error"), JOptionPane.ERROR_MESSAGE); 
     76            } 
     77 
    6178        } 
    6279    } 
     
    6683    } 
    6784    @Override protected void finish() { 
    68         if (sel != null) 
     85        if (sel != null) { 
    6986            Main.ds.setSelected(sel); 
     87        } 
    7088    } 
    7189} 
  • trunk/src/org/openstreetmap/josm/command/CoordinateConflictResolveCommand.java

    r1654 r1670  
    3333    /** the merge decision */ 
    3434    private final MergeDecisionType decision; 
    35  
    36  
    37     /** 
    38      * replies a (localized) display name for the type of an OSM primitive 
    39      *  
    40      * @param primitive the primitive 
    41      * @return a localized display name 
    42      */ 
    43     protected String getPrimitiveTypeAsString(OsmPrimitive primitive) { 
    44         if (primitive instanceof Node) return tr("node"); 
    45         if (primitive instanceof Way) return tr("way"); 
    46         if (primitive instanceof Relation) return tr("relation"); 
    47         return ""; 
    48     } 
    4935 
    5036    /** 
  • trunk/src/org/openstreetmap/josm/command/TagConflictResolveCommand.java

    r1654 r1670  
    1414import org.openstreetmap.josm.data.osm.Node; 
    1515import org.openstreetmap.josm.data.osm.OsmPrimitive; 
     16import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 
    1617import org.openstreetmap.josm.data.osm.Relation; 
    1718import org.openstreetmap.josm.data.osm.Way; 
     
    5253 
    5354    /** 
    54      * replies a (localized) display name for the type of an OSM primitive 
    55      *  
    56      * @param primitive the primitive 
    57      * @return a localized display name 
    58      */ 
    59     protected String getPrimitiveTypeAsString(OsmPrimitive primitive) { 
    60         if (primitive instanceof Node) return tr("node"); 
    61         if (primitive instanceof Way) return tr("way"); 
    62         if (primitive instanceof Relation) return tr("relation"); 
    63         return ""; 
    64     } 
    65  
    66     /** 
    6755     * constructor 
    6856     *  
     
    8270        return new DefaultMutableTreeNode( 
    8371                new JLabel( 
    84                         tr("Resolve {0} tag conflicts in {1} {2}",getNumDecidedConflicts(), getPrimitiveTypeAsString(my), my.id), 
     72                        tr("Resolve {0} tag conflicts in {1} {2}",getNumDecidedConflicts(), OsmPrimitiveType.from(my).getLocalizedDisplayNameSingular(), my.id), 
    8573                        ImageProvider.get("data", "object"), 
    8674                        JLabel.HORIZONTAL 
  • trunk/src/org/openstreetmap/josm/command/VersionConflictResolveCommand.java

    r1654 r1670  
    1313import org.openstreetmap.josm.data.osm.Node; 
    1414import org.openstreetmap.josm.data.osm.OsmPrimitive; 
     15import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 
    1516import org.openstreetmap.josm.data.osm.Relation; 
    1617import org.openstreetmap.josm.data.osm.Way; 
     
    3738    } 
    3839 
    39     //FIXME copied from TagConflictResolveCommand -> refactor 
    40     /** 
    41      * replies a (localized) display name for the type of an OSM primitive 
    42      *  
    43      * @param primitive the primitive 
    44      * @return a localized display name 
    45      */ 
    46     protected String getPrimitiveTypeAsString(OsmPrimitive primitive) { 
    47         if (primitive instanceof Node) return tr("node"); 
    48         if (primitive instanceof Way) return tr("way"); 
    49         if (primitive instanceof Relation) return tr("relation"); 
    50         return ""; 
    51     } 
    52  
    5340    @Override 
    5441    public MutableTreeNode description() { 
    5542        return new DefaultMutableTreeNode( 
    5643                new JLabel( 
    57                         tr("Resolve version conflicts for {0} {1}",getPrimitiveTypeAsString(my), my.id), 
     44                        tr("Resolve version conflicts for {0} {1}",OsmPrimitiveType.from(my).getLocalizedDisplayNameSingular(), my.id), 
    5845                        ImageProvider.get("data", "object"), 
    5946                        JLabel.HORIZONTAL 
  • trunk/src/org/openstreetmap/josm/data/osm/DataSet.java

    r1647 r1670  
    1010import java.util.LinkedList; 
    1111import java.util.List; 
     12import java.util.Set; 
    1213 
    1314import org.openstreetmap.josm.data.SelectionChangedListener; 
     15import static org.openstreetmap.josm.tools.I18n.tr; 
    1416 
    1517/** 
     
    7880        Collection<OsmPrimitive> o = new LinkedList<OsmPrimitive>(); 
    7981        for (OsmPrimitive osm : allPrimitives()) 
    80             if (!osm.deleted) 
     82            if (!osm.deleted) { 
    8183                o.add(osm); 
     84            } 
    8285        return o; 
    8386    } 
     
    8689        Collection<OsmPrimitive> o = new LinkedList<OsmPrimitive>(); 
    8790        for (OsmPrimitive osm : allPrimitives()) 
    88             if (!osm.deleted && !osm.incomplete) 
     91            if (!osm.deleted && !osm.incomplete) { 
    8992                o.add(osm); 
     93            } 
    9094        return o; 
    9195    } 
     
    9498        Collection<OsmPrimitive> o = new LinkedList<OsmPrimitive>(); 
    9599        for (OsmPrimitive osm : allPrimitives()) 
    96             if (!osm.deleted && !osm.incomplete && !(osm instanceof Relation)) 
     100            if (!osm.deleted && !osm.incomplete && !(osm instanceof Relation)) { 
    97101                o.add(osm); 
     102            } 
    98103        return o; 
    99104    } 
     
    150155        clearSelection(ways); 
    151156        clearSelection(relations); 
    152         for (OsmPrimitive osm : selection) 
     157        for (OsmPrimitive osm : selection) { 
    153158            osm.selected = true; 
     159        } 
    154160        fireSelectionChanged(selection); 
    155161    } 
     
    164170        clearSelection(relations); 
    165171        for (OsmPrimitive o : osm) 
    166             if (o != null) 
     172            if (o != null) { 
    167173                o.selected = true; 
     174            } 
    168175        fireSelectionChanged(Arrays.asList(osm)); 
    169176    } 
     
    176183        if (list == null) 
    177184            return; 
    178         for (OsmPrimitive osm : list) 
     185        for (OsmPrimitive osm : list) { 
    179186            osm.selected = false; 
     187        } 
    180188    } 
    181189 
     
    189197            return sel; 
    190198        for (OsmPrimitive osm : list) 
    191             if (osm.selected && !osm.deleted) 
     199            if (osm.selected && !osm.deleted) { 
    192200                sel.add(osm); 
     201            } 
    193202        return sel; 
    194203    } 
     
    200209     */ 
    201210    public static void fireSelectionChanged(Collection<? extends OsmPrimitive> sel) { 
    202         for (SelectionChangedListener l : selListeners) 
     211        for (SelectionChangedListener l : selListeners) { 
    203212            l.selectionChanged(sel); 
     213        } 
    204214    } 
    205215 
    206216    @Override public DataSet clone() { 
    207217        DataSet ds = new DataSet(); 
    208         for (Node n : nodes) 
     218        for (Node n : nodes) { 
    209219            ds.nodes.add(new Node(n)); 
    210         for (Way w : ways) 
     220        } 
     221        for (Way w : ways) { 
    211222            ds.ways.add(new Way(w)); 
    212         for (Relation e : relations) 
     223        } 
     224        for (Relation e : relations) { 
    213225            ds.relations.add(new Relation(e)); 
    214         for (DataSource source : dataSources) 
     226        } 
     227        for (DataSource source : dataSources) { 
    215228            ds.dataSources.add(new DataSource(source.bounds, source.origin)); 
     229        } 
    216230        ds.version = version; 
    217231        return ds; 
     
    260274        return selArr; 
    261275    } 
     276 
     277    /** 
     278     * returns a  primitive with a given id from the data set. null, if no such primitive 
     279     * exists 
     280     *  
     281     * @param id  the id, > 0 required 
     282     * @return the primitive 
     283     * @exception IllegalArgumentException thrown, if id <= 0 
     284     */ 
     285    public OsmPrimitive getPrimitiveById(long id) { 
     286        if (id <= 0) 
     287            throw new IllegalArgumentException(tr("parameter {0} > 0 required. Got {1}.", "id", id)); 
     288        for (OsmPrimitive primitive : nodes) { 
     289            if (primitive.id == id) return primitive; 
     290        } 
     291        for (OsmPrimitive primitive : ways) { 
     292            if (primitive.id == id) return primitive; 
     293        } 
     294        for (OsmPrimitive primitive : relations) { 
     295            if (primitive.id == id) return primitive; 
     296        } 
     297        return null; 
     298    } 
     299 
     300    public Set<Long> getPrimitiveIds() { 
     301        HashSet<Long> ret = new HashSet<Long>(); 
     302        for (OsmPrimitive primitive : nodes) { 
     303            ret.add(primitive.id); 
     304        } 
     305        for (OsmPrimitive primitive : ways) { 
     306            ret.add(primitive.id); 
     307        } 
     308        for (OsmPrimitive primitive : relations) { 
     309            ret.add(primitive.id); 
     310        } 
     311        return ret; 
     312    } 
    262313} 
  • trunk/src/org/openstreetmap/josm/data/osm/Relation.java

    r1598 r1670  
    7878    } 
    7979 
     80    @Override 
    8081    public String getName() { 
    8182        String name; 
     
    8485        } else { 
    8586            name = get("type"); 
    86             if (name == null) 
     87            if (name == null) { 
    8788                name = tr("relation"); 
     89            } 
    8890 
    8991            name += " ("; 
    90             if(names == null) 
    91               names = Main.pref.getCollection("relation.nameOrder", Arrays.asList(defnames)); 
     92            if(names == null) { 
     93                names = Main.pref.getCollection("relation.nameOrder", Arrays.asList(defnames)); 
     94            } 
    9295            String nameTag = null; 
    9396            for (String n : names) { 
    9497                nameTag = get(n); 
    95                 if (nameTag != null) break; 
     98                if (nameTag != null) { 
     99                    break; 
     100                } 
    96101            } 
    97             if (nameTag != null) 
     102            if (nameTag != null) { 
    98103                name += "\"" + nameTag + "\", "; 
     104            } 
    99105 
    100106            int mbno = members.size(); 
    101107            name += trn("{0} member", "{0} members", mbno, mbno) + ")"; 
    102             if(errors != null) 
     108            if(errors != null) { 
    103109                name = "*"+name; 
     110            } 
    104111        } 
    105112        return name; 
     
    113120        return false; 
    114121    } 
    115      
     122 
    116123    public RelationMember firstMember() { 
    117124        if (incomplete) return null; 
     
    122129        return (members.size() == 0) ? null : members.get(members.size() -1); 
    123130    } 
     131 
     132    /** 
     133     * removes all members with member.member == primitive 
     134     *  
     135     * @param primitive the primitive to check for 
     136     */ 
     137    public void removeMembersFor(OsmPrimitive primitive) { 
     138        if (primitive == null) 
     139            return; 
     140 
     141        ArrayList<RelationMember> todelete = new ArrayList<RelationMember>(); 
     142        for (RelationMember member: members) { 
     143            if (member.member == primitive) { 
     144                todelete.add(member); 
     145            } 
     146        } 
     147        members.removeAll(todelete); 
     148    } 
    124149} 
  • trunk/src/org/openstreetmap/josm/gui/MainMenu.java

    r1639 r1670  
    6262import org.openstreetmap.josm.actions.UnselectAllAction; 
    6363import org.openstreetmap.josm.actions.UpdateDataAction; 
     64import org.openstreetmap.josm.actions.UpdateSelectionAction; 
    6465import org.openstreetmap.josm.actions.UploadAction; 
    6566import org.openstreetmap.josm.actions.ZoomInAction; 
     
    9495    public final DownloadAction download = new DownloadAction(); 
    9596    public final JosmAction update = new UpdateDataAction(); 
     97    public final JosmAction updateSelection = new UpdateSelectionAction(); 
    9698    public final JosmAction upload = new UploadAction(); 
    9799    public final JosmAction exit = new ExitAction(); 
     
    194196        add(fileMenu, upload); 
    195197        add(fileMenu, update); 
     198        add(fileMenu, updateSelection); 
    196199        fileMenu.addSeparator(); 
    197200        add(fileMenu, exit); 
  • trunk/src/org/openstreetmap/josm/gui/PleaseWaitRunnable.java

    r1647 r1670  
    1717 
    1818import org.openstreetmap.josm.Main; 
     19import org.openstreetmap.josm.io.OsmTransferException; 
    1920import org.xml.sax.SAXException; 
    2021 
     
    109110                x.printStackTrace(); 
    110111                errorMessage = x.getMessage(); 
     112            } catch(OsmTransferException x) { 
     113                x.printStackTrace(); 
     114                if (x.getCause() != null) { 
     115                    errorMessage = x.getCause().getMessage(); 
     116                } else { 
     117                    errorMessage = x.getMessage(); 
     118                } 
    111119            } finally { 
    112120                closeDialog(); 
     
    134142     * is called. finish() is called in any case. 
    135143     */ 
    136     protected abstract void realRun() throws SAXException, IOException; 
     144    protected abstract void realRun() throws SAXException, IOException, OsmTransferException; 
    137145 
    138146    /** 
     
    158166                        Main.pleaseWaitDlg.dispose(); 
    159167                    } 
    160                     if (errorMessage != null && !silent) 
     168                    if (errorMessage != null && !silent) { 
    161169                        JOptionPane.showMessageDialog(Main.parent, errorMessage); 
     170                    } 
    162171                } 
    163172            }; 
    164173 
    165174            // make sure, this is called in the dispatcher thread ASAP 
    166             if (EventQueue.isDispatchThread()) 
     175            if (EventQueue.isDispatchThread()) { 
    167176                runnable.run(); 
    168             else 
     177            } else { 
    169178                EventQueue.invokeAndWait(runnable); 
     179            } 
    170180 
    171181        } catch (InterruptedException e) { 
  • trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java

    r1624 r1670  
    3636import org.openstreetmap.josm.data.osm.Node; 
    3737import org.openstreetmap.josm.data.osm.OsmPrimitive; 
     38import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 
    3839import org.openstreetmap.josm.data.osm.Relation; 
    3940import org.openstreetmap.josm.data.osm.RelationMember; 
     
    4445import org.openstreetmap.josm.gui.dialogs.ConflictDialog; 
    4546import org.openstreetmap.josm.io.OsmServerObjectReader; 
     47import org.openstreetmap.josm.io.OsmTransferException; 
    4648import org.openstreetmap.josm.tools.GBC; 
    4749import org.openstreetmap.josm.tools.Shortcut; 
     
    145147                            String key = propertyData.getValueAt(i, 0).toString(); 
    146148                            String value = propertyData.getValueAt(i, 1).toString(); 
    147                             if (key.length() > 0 && value.length() > 0) clone.put(key, value); 
     149                            if (key.length() > 0 && value.length() > 0) { 
     150                                clone.put(key, value); 
     151                            } 
    148152                        } 
    149153                        refreshTables(); 
     
    175179                { 
    176180                    sel = new ArrayList<OsmPrimitive>(cnt); 
    177                     for (int i : memberTable.getSelectedRows()) 
     181                    for (int i : memberTable.getSelectedRows()) { 
    178182                        sel.add((OsmPrimitive)memberTable.getValueAt(i, 1)); 
     183                    } 
    179184                } 
    180185                else 
     
    182187                    cnt = memberTable.getRowCount(); 
    183188                    sel = new ArrayList<OsmPrimitive>(cnt); 
    184                     for (int i = 0; i < cnt; ++i) 
     189                    for (int i = 0; i < cnt; ++i) { 
    185190                        sel.add((OsmPrimitive)memberTable.getValueAt(i, 1)); 
     191                    } 
    186192                } 
    187193                Main.ds.setSelected(sel); 
     
    239245 
    240246        buttonPanel.add(createButton(marktr("Add Selected"),"addselected", 
    241         tr("Add all currently selected objects as members"), KeyEvent.VK_D, new ActionListener() { 
     247                tr("Add all currently selected objects as members"), KeyEvent.VK_D, new ActionListener() { 
    242248            public void actionPerformed(ActionEvent e) { 
    243249                addSelected(); 
     
    246252 
    247253        buttonPanel.add(createButton(marktr("Remove Selected"),"removeselected", 
    248         tr("Remove all currently selected objects from relation"), KeyEvent.VK_S, new ActionListener() { 
     254                tr("Remove all currently selected objects from relation"), KeyEvent.VK_S, new ActionListener() { 
    249255            public void actionPerformed(ActionEvent e) { 
    250256                deleteSelected(); 
     
    259265 
    260266        buttonPanel.add(createButton(marktr("Remove"),"remove", 
    261         tr("Remove the member in the current table row from this relation"), KeyEvent.VK_M, new ActionListener() { 
     267                tr("Remove the member in the current table row from this relation"), KeyEvent.VK_M, new ActionListener() { 
    262268            public void actionPerformed(ActionEvent e) { 
    263269                int[] rows = memberTable.getSelectedRows(); 
     
    273279 
    274280        buttonPanel.add(createButton(marktr("Download Members"),"downloadincomplete", 
    275         tr("Download all incomplete ways and nodes in relation"), KeyEvent.VK_K, new ActionListener() { 
     281                tr("Download all incomplete ways and nodes in relation"), KeyEvent.VK_K, new ActionListener() { 
    276282            public void actionPerformed(ActionEvent e) { 
    277283                downloadRelationMembers(); 
     
    303309    protected void buttonAction(ActionEvent evt) { 
    304310        String a = evt.getActionCommand(); 
    305         if(applyChangesText.equals(a)) 
     311        if(applyChangesText.equals(a)) { 
    306312            applyChanges(); 
     313        } 
    307314 
    308315        setVisible(false); 
     
    348355                    break; 
    349356                } else if (m.member instanceof Relation) { 
    350                     if (m.member == this.relation) 
     357                    if (m.member == this.relation) { 
    351358                        break; 
     359                    } 
    352360                    m = ((Relation)m.member).lastMember(); 
    353361                    depth++; 
     
    366374                            break; 
    367375                        } else if (m.member instanceof Relation) { 
    368                             if (m.member == this.relation) 
     376                            if (m.member == this.relation) { 
    369377                                break; 
     378                            } 
    370379                            m = ((Relation)(m.member)).firstMember(); 
    371380                            depth++; 
     
    374383                        } 
    375384                    } 
    376                     if (way2 != null) 
     385                    if (way2 != null) { 
    377386                        break; 
     387                    } 
    378388                } 
    379389            } 
     
    404414                } 
    405415 
    406                 // end of section to determine linkedness.  
     416                // end of section to determine linkedness. 
    407417 
    408418                memberData.addRow(new Object[]{em.role, em.member, linked ? tr("yes") : tr("no")}); 
     
    416426    private SideButton createButton(String name, String iconName, String tooltip, int mnemonic, ActionListener actionListener) { 
    417427        return 
    418             new SideButton(name, iconName, "relationEditor", 
     428        new SideButton(name, iconName, "relationEditor", 
    419429                tooltip, 
    420430                Shortcut.registerShortcut("relationeditor:"+iconName, 
     
    422432                        mnemonic, 
    423433                        Shortcut.GROUP_MNEMONIC), 
    424                 actionListener 
    425             ); 
     434                        actionListener 
     435        ); 
    426436    } 
    427437 
     
    483493        for (RelationMember rm : clone.members) { 
    484494            if (rm != null) { 
    485                 while (m[i] != null) i++; 
     495                while (m[i] != null) { 
     496                    i++; 
     497                } 
    486498                m[i++] = rm; 
    487499            } 
     
    509521        } 
    510522        if (download) { 
    511             OsmServerObjectReader reader = new OsmServerObjectReader(clone.id, OsmServerObjectReader.TYPE_REL, true); 
     523            OsmServerObjectReader reader = new OsmServerObjectReader(clone.id, OsmPrimitiveType.RELATION, true); 
    512524            try { 
    513525                DataSet dataSet = reader.parseOsm(); 
     
    515527                    final MergeVisitor visitor = new MergeVisitor(Main.main 
    516528                            .editLayer().data, dataSet); 
    517                     for (final OsmPrimitive osm : dataSet.allPrimitives()) 
     529                    for (final OsmPrimitive osm : dataSet.allPrimitives()) { 
    518530                        osm.visit(visitor); 
     531                    } 
    519532                    visitor.fixReferences(); 
    520533 
    521534                    // copy the merged layer's data source info 
    522                     for (DataSource src : dataSet.dataSources) 
     535                    for (DataSource src : dataSet.dataSources) { 
    523536                        Main.main.editLayer().data.dataSources.add(src); 
     537                    } 
    524538                    Main.main.editLayer().fireDataChange(); 
    525539 
     
    530544                    JOptionPane.showMessageDialog(Main.parent, 
    531545                            tr("There were conflicts during import.")); 
    532                     if (!dlg.isVisible()) 
     546                    if (!dlg.isVisible()) { 
    533547                        dlg.action 
    534                                 .actionPerformed(new ActionEvent(this, 0, "")); 
    535                 } 
    536  
    537             } catch (SAXException e) { 
     548                        .actionPerformed(new ActionEvent(this, 0, "")); 
     549                    } 
     550                } 
     551            } catch(OsmTransferException e) { 
    538552                e.printStackTrace(); 
    539                 JOptionPane.showMessageDialog(this,tr("Error parsing server response.")+": "+e.getMessage(), 
    540                 tr("Error"), JOptionPane.ERROR_MESSAGE); 
    541             } catch (IOException e) { 
    542                 e.printStackTrace(); 
    543                 JOptionPane.showMessageDialog(this,tr("Cannot connect to server.")+": "+e.getMessage(), 
    544                 tr("Error"), JOptionPane.ERROR_MESSAGE); 
     553                if (e.getCause() != null) { 
     554                    if (e.getCause() instanceof SAXException) { 
     555                        JOptionPane.showMessageDialog(this,tr("Error parsing server response.")+": "+e.getCause().getMessage(), 
     556                                tr("Error"), JOptionPane.ERROR_MESSAGE); 
     557                    } else if(e.getCause() instanceof IOException) { 
     558                        JOptionPane.showMessageDialog(this,tr("Cannot connect to server.")+": "+e.getCause().getMessage(), 
     559                                tr("Error"), JOptionPane.ERROR_MESSAGE); 
     560                    } 
     561                } else { 
     562                    JOptionPane.showMessageDialog(this,tr("Error when communicating with server.")+": "+e.getMessage(), 
     563                            tr("Error"), JOptionPane.ERROR_MESSAGE); 
     564                } 
    545565            } 
    546566        } 
  • trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java

    r1646 r1670  
    5151import org.openstreetmap.josm.data.osm.Node; 
    5252import org.openstreetmap.josm.data.osm.OsmPrimitive; 
     53import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 
    5354import org.openstreetmap.josm.data.osm.Relation; 
    5455import org.openstreetmap.josm.data.osm.Way; 
     
    7778        public final int[] normal = new int[3]; 
    7879        public final int[] deleted = new int[3]; 
    79         public final String[] names = {"node", "way", "relation"}; 
     80        public final String[] names = { 
     81                OsmPrimitiveType.NODE.getAPIName(), 
     82                OsmPrimitiveType.WAY.getAPIName(), 
     83                OsmPrimitiveType.RELATION.getAPIName() 
     84        }; 
    8085 
    8186        private void inc(final OsmPrimitive osm, final int i) { 
    8287            normal[i]++; 
    83             if (osm.deleted) 
     88            if (osm.deleted) { 
    8489                deleted[i]++; 
     90            } 
    8591        } 
    8692 
     
    201207 
    202208        SimplePaintVisitor painter; 
    203         if (Main.pref.getBoolean("draw.wireframe")) 
     209        if (Main.pref.getBoolean("draw.wireframe")) { 
    204210            painter = new SimplePaintVisitor(); 
    205         else 
     211        } else { 
    206212            painter = new MapPaintVisitor(); 
     213        } 
    207214        painter.setGraphics(g); 
    208215        painter.setNavigatableComponent(mv); 
     
    216223        tool += undeletedSize(data.nodes)+" "+trn("node", "nodes", undeletedSize(data.nodes))+", "; 
    217224        tool += undeletedSize(data.ways)+" "+trn("way", "ways", undeletedSize(data.ways)); 
    218         if (data.version != null) tool += ", " + tr("version {0}", data.version); 
     225        if (data.version != null) { 
     226            tool += ", " + tr("version {0}", data.version); 
     227        } 
    219228        File f = getAssociatedFile(); 
    220         if (f != null) 
     229        if (f != null) { 
    221230            tool = "<html>"+tool+"<br>"+f.getPath()+"</html>"; 
     231        } 
    222232        return tool; 
    223233    } 
    224234 
    225235    @Override public void mergeFrom(final Layer from) { 
    226         final MergeVisitor visitor = new MergeVisitor(data,((OsmDataLayer)from).data); 
    227         for (final OsmPrimitive osm : ((OsmDataLayer)from).data.allPrimitives()) { 
    228 //            i++; 
    229 //            if(i%100 == 0) { 
    230 //                double perc = (((double)i) / ((double)max) * 100.0); 
    231 //                System.out.format(" " + (int)perc + "%%"); 
    232 //            } 
     236        mergeFrom(((OsmDataLayer)from).data); 
     237    } 
     238 
     239    /** 
     240     * merges the primitives in dataset <code>from</code> into the dataset of 
     241     * this layer 
     242     *  
     243     * @param from  the source data set 
     244     */ 
     245    public void mergeFrom(final DataSet from) { 
     246        final MergeVisitor visitor = new MergeVisitor(data,from); 
     247        for (final OsmPrimitive osm : from.allPrimitives()) { 
    233248            osm.visit(visitor); 
    234249        } 
    235250        visitor.fixReferences(); 
    236 //        System.out.println(""); 
    237251 
    238252        Area a = data.getDataSourceArea(); 
    239          
    240         // copy the merged layer's data source info;  
     253 
     254        // copy the merged layer's data source info; 
    241255        // only add source rectangles if they are not contained in the 
    242256        // layer already. 
    243         for (DataSource src : ((OsmDataLayer)from).data.dataSources) { 
    244             if (a == null || !a.contains(src.bounds.asRect())) 
     257        for (DataSource src : from.dataSources) { 
     258            if (a == null || !a.contains(src.bounds.asRect())) { 
    245259                data.dataSources.add(src); 
    246         } 
    247          
     260            } 
     261        } 
     262 
    248263        // copy the merged layer's API version, downgrade if required 
    249264        if (data.version == null) { 
    250             data.version = ((OsmDataLayer)from).data.version; 
     265            data.version = from.version; 
    251266        } else { 
    252             if ("0.5".equals(data.version) ^ "0.5".equals(((OsmDataLayer)from).data.version)) { 
    253                 System.err.println("Warning: mixing 0.6 and 0.5 data results in version 0.5"); 
     267            if ("0.5".equals(data.version) ^ "0.5".equals(from.version)) { 
     268                System.err.println(tr("Warning: mixing 0.6 and 0.5 data results in version 0.5")); 
    254269                data.version = "0.5"; 
    255270            } 
     
    263278        final ConflictDialog dlg = Main.map.conflictDialog; 
    264279        dlg.add(visitor.conflicts); 
    265         JOptionPane.showMessageDialog(Main.parent,tr("There were conflicts during import.")); 
    266         if (!dlg.isVisible()) 
     280        JOptionPane.showMessageDialog(Main.parent,tr("There were {0} conflicts during import.", visitor.conflicts.size())); 
     281        if (!dlg.isVisible()) { 
    267282            dlg.action.actionPerformed(new ActionEvent(this, 0, "")); 
     283        } 
    268284    } 
    269285 
     
    274290    @Override public void visitBoundingBox(final BoundingXYVisitor v) { 
    275291        for (final Node n : data.nodes) 
    276             if (!n.deleted && !n.incomplete) 
     292            if (!n.deleted && !n.incomplete) { 
    277293                v.visit(n); 
     294            } 
    278295    } 
    279296 
     
    299316        if (processed != null) { 
    300317            final Set<OsmPrimitive> processedSet = new HashSet<OsmPrimitive>(processed); 
    301             for (final Iterator<Node> it = data.nodes.iterator(); it.hasNext();) 
     318            for (final Iterator<Node> it = data.nodes.iterator(); it.hasNext();) { 
    302319                cleanIterator(it, processedSet); 
    303             for (final Iterator<Way> it = data.ways.iterator(); it.hasNext();) 
     320            } 
     321            for (final Iterator<Way> it = data.ways.iterator(); it.hasNext();) { 
    304322                cleanIterator(it, processedSet); 
    305             for (final Iterator<Relation> it = data.relations.iterator(); it.hasNext();) 
     323            } 
     324            for (final Iterator<Relation> it = data.relations.iterator(); it.hasNext();) { 
    306325                cleanIterator(it, processedSet); 
     326            } 
    307327        } 
    308328 
     
    330350            return; 
    331351        osm.modified = false; 
    332         if (osm.deleted) 
     352        if (osm.deleted) { 
    333353            it.remove(); 
     354        } 
    334355    } 
    335356 
     
    342363            return; 
    343364        this.modified = modified; 
    344         for (final ModifiedChangedListener l : listenerModified) 
     365        for (final ModifiedChangedListener l : listenerModified) { 
    345366            l.modifiedChanged(modified, this); 
     367        } 
    346368    } 
    347369 
     
    352374        int size = 0; 
    353375        for (final OsmPrimitive osm : list) 
    354             if (!osm.deleted) 
     376            if (!osm.deleted) { 
    355377                size++; 
     378            } 
    356379        return size; 
    357380    } 
     
    359382    @Override public Object getInfoComponent() { 
    360383        final DataCountVisitor counter = new DataCountVisitor(); 
    361         for (final OsmPrimitive osm : data.allPrimitives()) 
     384        for (final OsmPrimitive osm : data.allPrimitives()) { 
    362385            osm.visit(counter); 
     386        } 
    363387        final JPanel p = new JPanel(new GridBagLayout()); 
    364388        p.add(new JLabel(tr("{0} consists of:", name)), GBC.eol()); 
    365389        for (int i = 0; i < counter.normal.length; ++i) { 
    366390            String s = counter.normal[i]+" "+trn(counter.names[i],counter.names[i]+"s",counter.normal[i]); 
    367             if (counter.deleted[i] > 0) 
     391            if (counter.deleted[i] > 0) { 
    368392                s += tr(" ({0} deleted.)",counter.deleted[i]); 
     393            } 
    369394            p.add(new JLabel(s, ImageProvider.get("data", counter.names[i]), JLabel.HORIZONTAL), GBC.eop().insets(15,0,0,0)); 
    370395        } 
     
    375400 
    376401    @Override public Component[] getMenuEntries() { 
    377         if (Main.applet) { 
     402        if (Main.applet) 
    378403            return new Component[]{ 
    379                     new JMenuItem(new LayerListDialog.ShowHideLayerAction(this)), 
    380                     new JMenuItem(new LayerListDialog.DeleteLayerAction(this)), 
    381                     new JSeparator(), 
    382                     new JMenuItem(new RenameLayerAction(getAssociatedFile(), this)), 
    383                     new JSeparator(), 
    384                     new JMenuItem(new LayerListPopup.InfoAction(this))}; 
    385         } 
     404                new JMenuItem(new LayerListDialog.ShowHideLayerAction(this)), 
     405                new JMenuItem(new LayerListDialog.DeleteLayerAction(this)), 
     406                new JSeparator(), 
     407                new JMenuItem(new RenameLayerAction(getAssociatedFile(), this)), 
     408                new JSeparator(), 
     409                new JMenuItem(new LayerListPopup.InfoAction(this))}; 
    386410        return new Component[]{ 
    387411                new JMenuItem(new LayerListDialog.ShowHideLayerAction(this)), 
     
    409433        HashSet<Node> doneNodes = new HashSet<Node>(); 
    410434        for (Way w : data.ways) { 
    411             if (w.incomplete || w.deleted) continue; 
     435            if (w.incomplete || w.deleted) { 
     436                continue; 
     437            } 
    412438            GpxTrack trk = new GpxTrack(); 
    413439            gpxData.tracks.add(trk); 
    414440 
    415             if (w.get("name") != null) 
     441            if (w.get("name") != null) { 
    416442                trk.attr.put("name", w.get("name")); 
     443            } 
    417444 
    418445            ArrayList<WayPoint> trkseg = null; 
     
    429456                    doneNodes.add(n); 
    430457                } 
    431                 WayPoint wpt = new WayPoint(n.getCoor());                 
     458                WayPoint wpt = new WayPoint(n.getCoor()); 
    432459                if (!n.isTimestampEmpty()) 
    433460                { 
     
    442469        // records them? 
    443470        for (Node n : data.nodes) { 
    444             if (n.incomplete || n.deleted || doneNodes.contains(n)) continue; 
     471            if (n.incomplete || n.deleted || doneNodes.contains(n)) { 
     472                continue; 
     473            } 
    445474            WayPoint wpt = new WayPoint(n.getCoor()); 
    446475            if (!n.isTimestampEmpty()) { 
  • trunk/src/org/openstreetmap/josm/io/BoundingBoxDownloader.java

    r1465 r1670  
    5050                Main.pleaseWaitDlg.currentAction.setText(tr("Downloading points {0} to {1}...", i * 5000, ((i + 1) * 5000))); 
    5151                InputStream in = getInputStream(url+i, Main.pleaseWaitDlg); 
    52                 if (in == null) 
     52                if (in == null) { 
    5353                    break; 
     54                } 
    5455                GpxData currentGpx = new GpxReader(in, null).data; 
    5556                if (result == null) { 
     
    8990     * @return A data set containing all data retrieved from that url 
    9091     */ 
    91     public DataSet parseOsm() throws SAXException, IOException { 
     92    @Override 
     93    public DataSet parseOsm() throws OsmTransferException { 
    9294        try { 
    9395            Main.pleaseWaitDlg.progress.setValue(0); 
     
    106108            if (cancel) 
    107109                return null; 
    108             throw e; 
     110            throw new OsmTransferException(e); 
    109111        } catch (SAXException e) { 
     112            throw new OsmTransferException(e); 
     113        } catch(OsmTransferException e) { 
    110114            throw e; 
    111115        } catch (Exception e) { 
    112116            if (cancel) 
    113117                return null; 
    114             if (e instanceof RuntimeException) 
    115                 throw (RuntimeException)e; 
    116             throw new RuntimeException(e); 
     118            throw new OsmTransferException(e); 
    117119        } 
    118120    } 
  • trunk/src/org/openstreetmap/josm/io/OsmApi.java

    r1667 r1670  
    2929import org.openstreetmap.josm.Main; 
    3030import org.openstreetmap.josm.data.osm.Changeset; 
    31 import org.openstreetmap.josm.data.osm.Node; 
    3231import org.openstreetmap.josm.data.osm.OsmPrimitive; 
    33 import org.openstreetmap.josm.data.osm.Relation; 
    34 import org.openstreetmap.josm.data.osm.Way; 
     32import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 
    3533import org.openstreetmap.josm.data.osm.visitor.CreateOsmChangeVisitor; 
    3634import org.xml.sax.Attributes; 
     
    6765        if (api == null) { 
    6866            api = new OsmApi(serverUrl); 
     67            instances.put(serverUrl,api); 
    6968        } 
    7069        return api; 
     
    8079        String serverUrl = Main.pref.get("osm-server.url"); 
    8180        if (serverUrl == null) 
    82             throw new IllegalStateException(tr("preference {0} missing. Can't initialize OsmApi", "osm-server.url")); 
     81            throw new IllegalStateException(tr("preference ''{0}'' missing. Can't initialize OsmApi", "osm-server.url")); 
    8382        return getOsmApi(serverUrl); 
    8483    } 
     
    9695     */ 
    9796    private String version = null; 
    98  
    99     /** 
    100      * Maximum downloadable area from server (degrees squared), from capabilities response 
    101      * FIXME: make download dialog use this, instead of hard-coded default. 
    102      */ 
    103     private String maxArea = null; 
    10497 
    10598    /** the api capabilities */ 
     
    143136 
    144137    /** 
    145      * creates an instance of the OSM API. Initializes the server URL with the 
    146      * value of the preference <code>osm-server.url</code> 
    147      *  
    148      * @exception IllegalStateException thrown, if the preference <code>osm-server.url</code> is not set 
    149      */ 
    150     protected OsmApi() { 
    151         this.serverUrl = Main.pref.get("osm-server.url"); 
    152         if (serverUrl == null) 
    153             throw new IllegalStateException(tr("preference {0} missing. Can't initialize OsmApi", "osm-server.url")); 
    154     } 
    155  
    156     /** 
    157      * Helper that returns the lower-case type name of an OsmPrimitive 
    158      * @param o the primitive 
    159      * @return "node", "way", "relation", or "changeset" 
    160      */ 
    161     public static String which(OsmPrimitive o) { 
    162         if (o instanceof Node) return "node"; 
    163         if (o instanceof Way) return "way"; 
    164         if (o instanceof Relation) return "relation"; 
    165         if (o instanceof Changeset) return "changeset"; 
    166         return ""; 
    167     } 
    168  
    169     /** 
    170138     * Returns the OSM protocol version we use to talk to the server. 
    171139     * @return protocol version, or null if not yet negotiated. 
     
    185153    /** 
    186154     * Initializes this component by negotiating a protocol version with the server. 
    187      *  
    188      * @exception UnknownHostException thrown, if the API host is unknown 
    189      * @exception SocketTimeoutException thrown, if the connection to the API host  times out 
    190      * @exception ConnectException throw, if the connection to the API host fails 
    191      * @exception Exception any other exception 
     155     * 
     156     * @exception OsmApiInitializationException thrown, if an exception occurs 
    192157     */ 
    193158    public void initialize() throws OsmApiInitializationException { 
     
    238203 
    239204    /** 
    240      * Helper that makes an int from the first whitespace separated token in a string. 
    241      * @param s the string 
    242      * @return the integer represenation of the first token in the string 
    243      * @throws OsmTransferException if the string is empty or does not represent a number 
    244      */ 
    245     public static int parseInt(String s) throws OsmTransferException { 
    246         StringTokenizer t = new StringTokenizer(s); 
    247         try { 
    248             return Integer.parseInt(t.nextToken()); 
    249         } catch (Exception x) { 
    250             throw new OsmTransferException(tr("Cannot read numeric value from response")); 
    251         } 
    252     } 
    253  
    254     /** 
    255      * Helper that makes a long from the first whitespace separated token in a string. 
    256      * @param s the string 
    257      * @return the long represenation of the first token in the string 
    258      * @throws OsmTransferException if the string is empty or does not represent a number 
    259      */ 
    260     public static long parseLong(String s) throws OsmTransferException { 
    261         StringTokenizer t = new StringTokenizer(s); 
    262         try { 
    263             return Long.parseLong(t.nextToken()); 
    264         } catch (Exception x) { 
    265             throw new OsmTransferException(tr("Cannot read numeric value from response")); 
    266         } 
    267     } 
    268  
    269     /** 
    270205     * Returns the base URL for API requests, including the negotiated version number. 
    271206     * @return base URL string 
     
    293228    public void createPrimitive(OsmPrimitive osm) throws OsmTransferException { 
    294229        initialize(); 
    295         osm.id = parseLong(sendRequest("PUT", which(osm)+"/create", toXml(osm, true))); 
    296         osm.version = 1; 
     230        String ret = ""; 
     231        try { 
     232            ret = sendRequest("PUT", OsmPrimitiveType.from(osm).getAPIName()+"/create", toXml(osm, true)); 
     233            osm.id = Long.parseLong(ret.trim()); 
     234            osm.version = 1; 
     235        } catch(NumberFormatException e){ 
     236            throw new OsmTransferException(tr("unexpected format of id replied by the server, got ''{0}''", ret)); 
     237        } 
    297238    } 
    298239 
     
    309250        if (version.equals("0.5")) { 
    310251            // legacy mode does not return the new object version. 
    311             sendRequest("PUT", which(osm)+"/" + osm.id, toXml(osm, true)); 
     252            sendRequest("PUT", OsmPrimitiveType.from(osm).getAPIName()+"/" + osm.id, toXml(osm, true)); 
    312253        } else { 
     254            String ret = null; 
    313255            // normal mode (0.6 and up) returns new object version. 
    314             osm.version = parseInt(sendRequest("PUT", which(osm)+"/" + osm.id, toXml(osm, true))); 
     256            try { 
     257                ret = sendRequest("PUT", OsmPrimitiveType.from(osm).getAPIName()+"/" + osm.id, toXml(osm, true)); 
     258                osm.version = Integer.parseInt(ret.trim()); 
     259            } catch(NumberFormatException e) { 
     260                throw new OsmTransferException(tr("unexpected format of new version of modified primitive ''{0}'', got ''{1}''", osm.id, ret)); 
     261            } 
    315262        } 
    316263    } 
     
    324271        initialize(); 
    325272        // legacy mode does not require payload. normal mode (0.6 and up) requires payload for version matching. 
    326         sendRequest("DELETE", which(osm)+"/" + osm.id, version.equals("0.5") ? null : toXml(osm, false)); 
     273        sendRequest("DELETE", OsmPrimitiveType.from(osm).getAPIName()+"/" + osm.id, version.equals("0.5") ? null : toXml(osm, false)); 
    327274    } 
    328275 
     
    334281    public void createChangeset(String comment) throws OsmTransferException { 
    335282        changeset = new Changeset(); 
    336         Main.pleaseWaitDlg.currentAction.setText(tr("Opening changeset...")); 
     283        notifyStatusMessage(tr("Opening changeset...")); 
    337284        Properties sysProp = System.getProperties(); 
    338285        Object ua = sysProp.get("http.agent"); 
     
    349296    public void stopChangeset() throws OsmTransferException { 
    350297        initialize(); 
    351         Main.pleaseWaitDlg.currentAction.setText(tr("Closing changeset...")); 
     298        notifyStatusMessage(tr("Closing changeset...")); 
    352299        sendRequest("PUT", "changeset" + "/" + changeset.id + "/close", null); 
    353300        changeset = null; 
     
    372319        CreateOsmChangeVisitor duv = new CreateOsmChangeVisitor(changeset, OsmApi.this); 
    373320 
     321        notifyStatusMessage(tr("Preparing...")); 
    374322        for (OsmPrimitive osm : list) { 
    375             int progress = Main.pleaseWaitDlg.progress.getValue(); 
    376             Main.pleaseWaitDlg.currentAction.setText(tr("Preparing...")); 
    377323            osm.visit(duv); 
    378             Main.pleaseWaitDlg.progress.setValue(progress+1); 
    379         } 
    380  
    381         Main.pleaseWaitDlg.currentAction.setText(tr("Uploading...")); 
     324            notifyRelativeProgress(1); 
     325        } 
     326        notifyStatusMessage(tr("Uploading...")); 
    382327 
    383328        String diff = duv.getDocument(); 
     
    517462        } 
    518463    } 
     464 
     465    /** 
     466     * notifies any listeners about the current state of this API. Currently just 
     467     * displays the message in the global progress dialog, see {@see Main#pleaseWaitDlg} 
     468     *  
     469     * @param message a status message. 
     470     */ 
     471    protected void notifyStatusMessage(String message) { 
     472        Main.pleaseWaitDlg.currentAction.setText(message); 
     473    } 
     474 
     475    /** 
     476     * notifies any listeners about the current about a relative progress. Currently just 
     477     * increments the progress monitor in the in the global progress dialog, see {@see Main#pleaseWaitDlg} 
     478     *  
     479     * @param int the delta 
     480     */ 
     481    protected void notifyRelativeProgress(int delta) { 
     482        int current= Main.pleaseWaitDlg.progress.getValue(); 
     483        Main.pleaseWaitDlg.progress.setValue(current + delta); 
     484    } 
    519485} 
  • trunk/src/org/openstreetmap/josm/io/OsmConnection.java

    r1523 r1670  
    2222 
    2323import org.openstreetmap.josm.Main; 
    24 import org.openstreetmap.josm.gui.ExtendedDialog;  
     24import org.openstreetmap.josm.gui.ExtendedDialog; 
    2525import org.openstreetmap.josm.tools.Base64; 
    2626import org.openstreetmap.josm.tools.GBC; 
     
    3333 */ 
    3434public class OsmConnection { 
    35  
    36     public static class OsmParseException extends Exception { 
    37         public OsmParseException() {super();} 
    38         public OsmParseException(String message, Throwable cause) {super(message, cause);} 
    39         public OsmParseException(String message) {super(message);} 
    40         public OsmParseException(Throwable cause) {super(cause);} 
    41     } 
    4235 
    4336    protected boolean cancel = false; 
     
    7770            if (passwordtried || username.equals("") || password.equals("")) { 
    7871                JPanel p = new JPanel(new GridBagLayout()); 
    79                 if (!username.equals("") && !password.equals("")) 
     72                if (!username.equals("") && !password.equals("")) { 
    8073                    p.add(new JLabel(tr("Incorrect password or username.")), GBC.eop()); 
     74                } 
    8175                p.add(new JLabel(tr("Username")), GBC.std().insets(0,0,10,0)); 
    8276                JTextField usernameField = new JTextField(username, 20); 
     
    9286                p.add(savePassword, GBC.eop()); 
    9387 
    94                 int choice = new ExtendedDialog(Main.parent,  
    95                         tr("Enter Password"),  
     88                int choice = new ExtendedDialog(Main.parent, 
     89                        tr("Enter Password"), 
    9690                        p, 
    97                         new String[] {tr("Login"), tr("Cancel")},  
    98                         new String[] {"ok.png", "cancel.png"}).getValue();   
    99                  
     91                        new String[] {tr("Login"), tr("Cancel")}, 
     92                        new String[] {"ok.png", "cancel.png"}).getValue(); 
     93 
    10094                if (choice != 1) { 
    10195                    authCancelled = true; 
  • trunk/src/org/openstreetmap/josm/io/OsmServerLocationReader.java

    r1523 r1670  
    2222     * Method to download OSM files from somewhere 
    2323     */ 
    24     public DataSet parseOsm() throws SAXException, IOException { 
     24    @Override 
     25    public DataSet parseOsm() throws OsmTransferException { 
    2526        try { 
    2627            Main.pleaseWaitDlg.progress.setValue(0); 
     
    3233            Main.pleaseWaitDlg.currentAction.setText(tr("Downloading OSM data...")); 
    3334            final DataSet data = OsmReader.parseDataSet(in, null, Main.pleaseWaitDlg); 
    34 //          Bounds bounds = new Bounds(new LatLon(lat1, lon1), new LatLon(lat2, lon2)); 
    35 //          DataSource src = new DataSource(bounds, origin); 
    36 //          data.dataSources.add(src); 
    3735            in.close(); 
    3836            activeConnection = null; 
     
    4139            if (cancel) 
    4240                return null; 
    43             throw e; 
     41            throw new OsmTransferException(e); 
    4442        } catch (SAXException e) { 
     43            throw new OsmTransferException(e); 
     44        } catch(OsmTransferException e) { 
    4545            throw e; 
    4646        } catch (Exception e) { 
    4747            if (cancel) 
    4848                return null; 
    49             if (e instanceof RuntimeException) 
    50                 throw (RuntimeException)e; 
    51             throw new RuntimeException(e); 
     49            throw new OsmTransferException(e); 
    5250        } 
    5351    } 
  • trunk/src/org/openstreetmap/josm/io/OsmServerObjectReader.java

    r1523 r1670  
    77import java.io.InputStream; 
    88 
     9import javax.swing.JOptionPane; 
     10 
    911import org.openstreetmap.josm.Main; 
    1012import org.openstreetmap.josm.data.osm.DataSet; 
     13import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 
    1114import org.xml.sax.SAXException; 
    12  
    13 import javax.swing.JOptionPane; 
    1415 
    1516public class OsmServerObjectReader extends OsmServerReader { 
    1617 
    17     public final static  String TYPE_WAY = "way"; 
    18     public final static  String TYPE_REL = "relation"; 
    19     public final static  String TYPE_NODE = "node"; 
    20  
    2118    long id; 
    22     String type; 
     19    OsmPrimitiveType type; 
    2320    boolean full; 
    2421 
    25     public OsmServerObjectReader(long id, String type, boolean full) { 
     22    public OsmServerObjectReader(long id, OsmPrimitiveType type, boolean full) { 
    2623        this.id = id; 
    2724        this.type = type; 
     
    3431     * @throws IOException 
    3532     */ 
    36     public DataSet parseOsm() throws SAXException, IOException { 
     33    @Override 
     34    public DataSet parseOsm() throws OsmTransferException { 
    3735        try { 
    3836            Main.pleaseWaitDlg.progress.setValue(0); 
    3937            Main.pleaseWaitDlg.currentAction.setText(tr("Contacting OSM Server...")); 
    4038            StringBuffer sb = new StringBuffer(); 
    41             sb.append(type); 
     39            sb.append(type.getAPIName()); 
    4240            sb.append("/"); 
    4341            sb.append(id); 
    44             if (full) 
     42            if (full && ! type.equals(OsmPrimitiveType.NODE)) { 
    4543                sb.append("/full"); 
     44            } 
    4645 
    4746            final InputStream in = getInputStream(sb.toString(), Main.pleaseWaitDlg); 
     
    5251            final DataSet data = osm.getDs(); 
    5352 
    54 //          Bounds bounds = new Bounds(new LatLon(lat1, lon1), new LatLon(lat2, lon2)); 
    55 //          DataSource src = new DataSource(bounds, origin); 
    56 //          data.dataSources.add(src); 
    5753            if (osm.getParseNotes().length() != 0) { 
    5854                JOptionPane.showMessageDialog(Main.parent, osm.getParseNotes()); 
     
    6460            if (cancel) 
    6561                return null; 
    66             throw e; 
     62            throw new OsmTransferException(e); 
    6763        } catch (SAXException e) { 
     64            throw new OsmTransferException(e); 
     65        } catch(OsmTransferException e) { 
    6866            throw e; 
    6967        } catch (Exception e) { 
    7068            if (cancel) 
    7169                return null; 
    72             if (e instanceof RuntimeException) 
    73                 throw (RuntimeException)e; 
    74             throw new RuntimeException(e); 
     70            throw new OsmTransferException(e); 
    7571        } 
    7672    } 
  • trunk/src/org/openstreetmap/josm/io/OsmServerReader.java

    r1664 r1670  
    44import static org.openstreetmap.josm.tools.I18n.tr; 
    55 
    6 import java.io.IOException; 
     6import java.io.BufferedReader; 
    77import java.io.InputStream; 
     8import java.io.InputStreamReader; 
    89import java.net.HttpURLConnection; 
     10import java.net.MalformedURLException; 
    911import java.net.URL; 
     12import java.util.zip.GZIPInputStream; 
    1013import java.util.zip.Inflater; 
    1114import java.util.zip.InflaterInputStream; 
    12 import java.util.zip.GZIPInputStream; 
    1315 
    1416import javax.swing.JOptionPane; 
     
    1719import org.openstreetmap.josm.data.osm.DataSet; 
    1820import org.openstreetmap.josm.gui.PleaseWaitDialog; 
    19 import org.xml.sax.SAXException; 
    2021 
    2122/** 
     
    3940     * @return An reader reading the input stream (servers answer) or <code>null</code>. 
    4041     */ 
    41     protected InputStream getInputStream(String urlStr, PleaseWaitDialog pleaseWaitDlg) throws IOException { 
    42  
    43         // initialize API. Abort download in case of configuration or network 
    44         // errors 
    45         // 
    46         try { 
    47             api.initialize(); 
    48         } catch(Exception e) { 
    49             JOptionPane.showMessageDialog( 
    50                     null, 
    51                     tr(   "Failed to initialize communication with the OSM server {0}.\n" 
    52                             + "Check the server URL in your preferences and your internet connection.", 
    53                             Main.pref.get("osm-server.url") 
    54                     ), 
    55                     tr("Error"), 
    56                     JOptionPane.ERROR_MESSAGE 
    57             ); 
    58             e.printStackTrace(); 
    59             return null; 
    60         } 
    61  
     42    protected InputStream getInputStream(String urlStr, PleaseWaitDialog pleaseWaitDlg) throws OsmTransferException  { 
     43        api.initialize(); 
    6244        urlStr = api.getBaseUrl() + urlStr; 
    6345        return getInputStreamRaw(urlStr, pleaseWaitDlg); 
    6446    } 
    6547 
    66     protected InputStream getInputStreamRaw(String urlStr, PleaseWaitDialog pleaseWaitDlg) throws IOException { 
    67  
    68         //        System.out.println("download: "+urlStr); 
    69         URL url = new URL(urlStr); 
    70         activeConnection = (HttpURLConnection)url.openConnection(); 
     48    protected InputStream getInputStreamRaw(String urlStr, PleaseWaitDialog pleaseWaitDlg) throws OsmTransferException { 
     49        URL url = null; 
     50        try { 
     51            url = new URL(urlStr); 
     52        } catch(MalformedURLException e) { 
     53            throw new OsmTransferException(e); 
     54        } 
     55        try { 
     56            activeConnection = (HttpURLConnection)url.openConnection(); 
     57        } catch(Exception e) { 
     58            throw new OsmTransferException(tr("Failed to open connection to API {0}", url.toExternalForm()), e); 
     59        } 
    7160        if (cancel) { 
    7261            activeConnection.disconnect(); 
     
    8170 
    8271        try { 
     72            System.out.println("GET " + url); 
    8373            activeConnection.connect(); 
     74        } catch (Exception e) { 
     75            throw new OsmTransferException(tr("Couldn't connect to the osm server. Please check your internet connection."), e); 
    8476        } 
    85         catch (Exception e) { 
    86             throw new IOException(tr("Couldn't connect to the osm server. Please check your internet connection.")); 
     77        try { 
     78            if (isAuthCancelled() && activeConnection.getResponseCode() == HttpURLConnection.HTTP_UNAUTHORIZED) 
     79                throw new OsmApiException(HttpURLConnection.HTTP_UNAUTHORIZED,null,null); 
     80 
     81            if (activeConnection.getResponseCode() != HttpURLConnection.HTTP_OK) { 
     82                String errorHeader = activeConnection.getHeaderField("Error"); 
     83                InputStream i = null; 
     84                i = activeConnection.getErrorStream(); 
     85                StringBuilder errorBody = new StringBuilder(); 
     86                if (i != null) { 
     87                    BufferedReader in = new BufferedReader(new InputStreamReader(i)); 
     88                    String s; 
     89                    while((s = in.readLine()) != null) { 
     90                        errorBody.append(s); 
     91                        errorBody.append("\n"); 
     92                    } 
     93                } 
     94 
     95                throw new OsmApiException(activeConnection.getResponseCode(), errorHeader, errorBody.toString()); 
     96            } 
     97 
     98            String encoding = activeConnection.getContentEncoding(); 
     99            InputStream inputStream = new ProgressInputStream(activeConnection, pleaseWaitDlg); 
     100            if (encoding != null && encoding.equalsIgnoreCase("gzip")) { 
     101                inputStream = new GZIPInputStream(inputStream); 
     102            } 
     103            else if (encoding != null && encoding.equalsIgnoreCase("deflate")) { 
     104                inputStream = new InflaterInputStream(inputStream, new Inflater(true)); 
     105            } 
     106            return inputStream; 
     107        } catch(Exception e) { 
     108            if (e instanceof OsmTransferException) 
     109                throw (OsmTransferException)e; 
     110            else 
     111                throw new OsmTransferException(e); 
     112 
    87113        } 
    88  
    89         if (isAuthCancelled() && activeConnection.getResponseCode() == 401) 
    90             return null; 
    91         if (activeConnection.getResponseCode() == 500) 
    92             throw new IOException(tr("Server returned internal error. Try a reduced area or retry after waiting some time.")); 
    93  
    94         String encoding = activeConnection.getContentEncoding(); 
    95         InputStream inputStream = new ProgressInputStream(activeConnection, pleaseWaitDlg); 
    96         if (encoding != null && encoding.equalsIgnoreCase("gzip")) { 
    97             inputStream = new GZIPInputStream(inputStream); 
    98         } 
    99         else if (encoding != null && encoding.equalsIgnoreCase("deflate")) { 
    100             inputStream = new InflaterInputStream(inputStream, new Inflater(true)); 
    101         } 
    102         return inputStream; 
    103114    } 
    104115 
    105     public abstract DataSet parseOsm() throws SAXException, IOException; 
     116    public abstract DataSet parseOsm() throws OsmTransferException; 
    106117 
    107118} 
  • trunk/src/org/openstreetmap/josm/io/OsmServerWriter.java

    r1664 r1670  
    101101        boolean useChangeset = Main.pref.getBoolean("osm-server.atomic-upload", apiVersion.compareTo("0.6")>=0); 
    102102        if (useChangeset && ! canUseChangeset) { 
    103             System.out.println(tr("WARNING: preference '{0}' or api version {1} of dataset requires to use changesets, but API is not handle them. Ignoring changesets.", "osm-server.atomic-upload", apiVersion)); 
     103            System.out.println(tr("WARNING: preference ''{0}'' or api version ''{1}'' of dataset requires to use changesets, but API is not handle them. Ignoring changesets.", "osm-server.atomic-upload", apiVersion)); 
    104104            useChangeset = false; 
    105105        } 
  • trunk/src/org/openstreetmap/josm/io/OsmWriter.java

    r1640 r1670  
    1111import org.openstreetmap.josm.data.osm.Node; 
    1212import org.openstreetmap.josm.data.osm.OsmPrimitive; 
     13import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 
    1314import org.openstreetmap.josm.data.osm.Relation; 
    1415import org.openstreetmap.josm.data.osm.RelationMember; 
     
    2526 
    2627    public final String DEFAULT_API_VERSION = "0.6"; 
    27      
     28 
    2829    /** 
    2930     * The counter for newly created objects. Starts at -1 and goes down. 
    3031     */ 
    3132    private long newIdCounter = -1; 
    32   
     33 
    3334    /** 
    3435     * All newly created ids and their primitive that uses it. This is a back reference 
     
    4142    private String version; 
    4243    private Changeset changeset; 
    43      
     44 
    4445    public OsmWriter(PrintWriter out, boolean osmConform, String version) { 
    4546        super(out); 
     
    4748        this.version = (version == null ? DEFAULT_API_VERSION : version); 
    4849    } 
    49      
     50 
    5051    public void setWithBody(boolean wb) { 
    5152        this.withBody = wb; 
     
    5758        this.version = v; 
    5859    } 
    59      
     60 
    6061    public void header() { 
    6162        out.println("<?xml version='1.0' encoding='UTF-8'?>"); 
     
    7071    public void writeContent(DataSet ds) { 
    7172        for (Node n : ds.nodes) 
    72             if (shouldWrite(n)) 
     73            if (shouldWrite(n)) { 
    7374                visit(n); 
     75            } 
    7476        for (Way w : ds.ways) 
    75             if (shouldWrite(w)) 
     77            if (shouldWrite(w)) { 
    7678                visit(w); 
     79            } 
    7780        for (Relation e : ds.relations) 
    78             if (shouldWrite(e)) 
     81            if (shouldWrite(e)) { 
    7982                visit(e); 
     83            } 
    8084    } 
    8185 
     
    100104        out.print(" lat='"+n.getCoor().lat()+"' lon='"+n.getCoor().lon()+"'"); 
    101105        if (!withBody) { 
    102             out.println("/>");   
     106            out.println("/>"); 
    103107        } else { 
    104108            addTags(n, "node", true); 
     
    110114        addCommon(w, "way"); 
    111115        if (!withBody) { 
    112             out.println("/>");   
     116            out.println("/>"); 
    113117        } else { 
    114118            out.println(">"); 
    115             for (Node n : w.nodes) 
     119            for (Node n : w.nodes) { 
    116120                out.println("    <nd ref='"+getUsedId(n)+"' />"); 
     121            } 
    117122            addTags(w, "way", false); 
    118123        } 
     
    123128        addCommon(e, "relation"); 
    124129        if (!withBody) { 
    125             out.println("/>");   
     130            out.println("/>"); 
    126131        } else { 
    127132            out.println(">"); 
    128133            for (RelationMember em : e.members) { 
    129134                out.print("    <member type='"); 
    130                 out.print(OsmApi.which(em.member)); 
     135                out.print(OsmPrimitiveType.from(em.member).getAPIName()); 
    131136                out.println("' ref='"+getUsedId(em.member)+"' role='" + 
    132137                        XmlWriter.encode(em.role == null ? "" : em.role) + "' />"); 
     
    160165    private void addTags(OsmPrimitive osm, String tagname, boolean tagOpen) { 
    161166        if (osm.keys != null) { 
    162             if (tagOpen) 
     167            if (tagOpen) { 
    163168                out.println(">"); 
    164             for (Entry<String, String> e : osm.keys.entrySet()) 
     169            } 
     170            for (Entry<String, String> e : osm.keys.entrySet()) { 
    165171                out.println("    <tag k='"+ XmlWriter.encode(e.getKey()) + 
    166172                        "' v='"+XmlWriter.encode(e.getValue())+ "' />"); 
     173            } 
    167174            out.println("  </" + tagname + ">"); 
    168         } else if (tagOpen) 
     175        } else if (tagOpen) { 
    169176            out.println(" />"); 
    170         else 
     177        } else { 
    171178            out.println("  </" + tagname + ">"); 
     179        } 
    172180    } 
    173181 
     
    180188        out.print("  <"+tagname); 
    181189        if (id != 0) { 
    182              out.print(" id='"+getUsedId(osm)+"'"); 
     190            out.print(" id='"+getUsedId(osm)+"'"); 
    183191        } 
    184192        if (!osmConform) { 
    185193            String action = null; 
    186             if (osm.deleted) 
     194            if (osm.deleted) { 
    187195                action = "delete"; 
    188             else if (osm.modified) 
     196            } else if (osm.modified) { 
    189197                action = "modify"; 
    190             if (action != null) 
     198            } 
     199            if (action != null) { 
    191200                out.print(" action='"+action+"'"); 
     201            } 
    192202        } 
    193203        if (!osm.isTimestampEmpty()) { 
     
    199209        } 
    200210        out.print(" visible='"+osm.visible+"'"); 
    201         if (osm.version != -1) 
     211        if (osm.version != -1) { 
    202212            out.print(" version='"+osm.version+"'"); 
    203         if (this.changeset != null && this.changeset.id != 0) 
     213        } 
     214        if (this.changeset != null && this.changeset.id != 0) { 
    204215            out.print(" changeset='"+this.changeset.id+"'" ); 
    205     } 
    206      
     216        } 
     217    } 
     218 
    207219    public void close() { 
    208220        out.close(); 
    209221    } 
    210      
     222 
    211223    public void flush() { 
    212224        out.flush(); 
  • trunk/src/org/openstreetmap/josm/io/ProgressInputStream.java

    r1169 r1670  
    2222    private PleaseWaitDialog pleaseWaitDlg; 
    2323 
    24     public class OsmServerException extends IOException { 
    25         private OsmServerException(String e) { 
    26             super(e); 
    27         } 
    28     } 
    29  
    30     public ProgressInputStream(URLConnection con, PleaseWaitDialog pleaseWaitDlg) throws IOException, OsmServerException { 
     24    public ProgressInputStream(URLConnection con, PleaseWaitDialog pleaseWaitDlg) throws OsmTransferException { 
    3125        this.connection = con; 
    3226 
     
    3529        } catch (IOException e) { 
    3630            if (con.getHeaderField("Error") != null) 
    37                 throw new OsmServerException(tr(con.getHeaderField("Error"))); 
    38             throw e; 
     31                throw new OsmTransferException(tr(con.getHeaderField("Error"))); 
     32            throw new OsmTransferException(e); 
    3933        } 
    4034 
     
    4337        if (pleaseWaitDlg == null) 
    4438            return; 
    45         if (contentLength > 0) 
     39        if (contentLength > 0) { 
    4640            pleaseWaitDlg.progress.setMaximum(contentLength); 
    47         else 
     41        } else { 
    4842            pleaseWaitDlg.progress.setMaximum(0); 
     43        } 
    4944        pleaseWaitDlg.progress.setValue(0); 
    5045    } 
     
    5651    @Override public int read(byte[] b, int off, int len) throws IOException { 
    5752        int read = in.read(b, off, len); 
    58         if (read != -1) 
     53        if (read != -1) { 
    5954            advanceTicker(read); 
     55        } 
    6056        return read; 
    6157    } 
     
    6359    @Override public int read() throws IOException { 
    6460        int read = in.read(); 
    65         if (read != -1) 
     61        if (read != -1) { 
    6662            advanceTicker(1); 
     63        } 
    6764        return read; 
    6865    } 
     
    7673            return; 
    7774 
    78         if (pleaseWaitDlg.progress.getMaximum() == 0 && connection.getContentLength() != -1) 
     75        if (pleaseWaitDlg.progress.getMaximum() == 0 && connection.getContentLength() != -1) { 
    7976            pleaseWaitDlg.progress.setMaximum(connection.getContentLength()); 
     77        } 
    8078 
    8179        readSoFar += amount; 
     
    8987            String cur = pleaseWaitDlg.currentAction.getText(); 
    9088            int i = cur.indexOf(' '); 
    91             if (i != -1) 
     89            if (i != -1) { 
    9290                cur = cur.substring(0, i) + progStr; 
    93             else 
     91            } else { 
    9492                cur += progStr; 
     93            } 
    9594            pleaseWaitDlg.currentAction.setText(cur); 
    9695        } 
Note: See TracChangeset for help on using the changeset viewer.