Changeset 1670 in josm for trunk/src/org


Ignore:
Timestamp:
2009-06-15T20:22:46+02:00 (15 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/src/org/openstreetmap/josm
Files:
14 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.