source: josm/trunk/src/org/openstreetmap/josm/io/OsmServerWriter.java@ 1608

Last change on this file since 1608 was 1608, checked in by stoecker, 15 years ago

close #2633 - patch by Gubaer - better error message for server aborts

  • Property svn:eol-style set to native
File size: 6.2 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.io;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.util.Collection;
7import java.util.LinkedList;
8import java.util.List;
9
10import javax.swing.JOptionPane;
11
12import org.openstreetmap.josm.Main;
13import org.openstreetmap.josm.actions.UploadAction;
14import org.openstreetmap.josm.data.osm.OsmPrimitive;
15import org.openstreetmap.josm.data.osm.visitor.NameVisitor;
16import org.openstreetmap.josm.gui.historycombobox.JHistoryComboBox;
17import org.openstreetmap.josm.gui.historycombobox.StringUtils;
18
19/**
20 * Class that uploads all changes to the osm server.
21 *
22 * This is done like this: - All objects with id = 0 are uploaded as new, except
23 * those in deleted, which are ignored - All objects in deleted list are
24 * deleted. - All remaining objects with modified flag set are updated.
25 */
26public class OsmServerWriter {
27
28 /**
29 * This list contains all successfully processed objects. The caller of
30 * upload* has to check this after the call and update its dataset.
31 *
32 * If a server connection error occurs, this may contain fewer entries
33 * than where passed in the list to upload*.
34 */
35 public Collection<OsmPrimitive> processed;
36
37
38 private OsmApi api = new OsmApi();
39
40 private static final int MSECS_PER_SECOND = 1000;
41 private static final int SECONDS_PER_MINUTE = 60;
42 private static final int MSECS_PER_MINUTE = MSECS_PER_SECOND * SECONDS_PER_MINUTE;
43
44 long uploadStartTime;
45
46 public String timeLeft(int progress, int list_size) {
47 long now = System.currentTimeMillis();
48 long elapsed = now - uploadStartTime;
49 if (elapsed == 0)
50 elapsed = 1;
51 float uploads_per_ms = (float)progress / elapsed;
52 float uploads_left = list_size - progress;
53 int ms_left = (int)(uploads_left / uploads_per_ms);
54 int minutes_left = ms_left / MSECS_PER_MINUTE;
55 int seconds_left = (ms_left / MSECS_PER_SECOND) % SECONDS_PER_MINUTE ;
56 String time_left_str = Integer.toString(minutes_left) + ":";
57 if (seconds_left < 10)
58 time_left_str += "0";
59 time_left_str += Integer.toString(seconds_left);
60 return time_left_str;
61 }
62
63 /**
64 * Send the dataset to the server.
65 * @param the_version version of the data set
66 * @param list list of objects to send
67 */
68 public void uploadOsm(String the_version, Collection<OsmPrimitive> list) {
69 processed = new LinkedList<OsmPrimitive>();
70
71 // initialize API. Abort upload in case of configuration or network
72 // errors
73 //
74 try {
75 api.initialize();
76 } catch(Exception e) {
77 JOptionPane.showMessageDialog(
78 null,
79 tr( "Failed to initialize communication with the OSM server {0}.\n"
80 + "Check the server URL in your preferences and your internet connection.",
81 Main.pref.get("osm-server.url")
82 ),
83 tr("Error"),
84 JOptionPane.ERROR_MESSAGE
85 );
86 e.printStackTrace();
87 return;
88 }
89
90
91 Main.pleaseWaitDlg.progress.setMaximum(list.size());
92 Main.pleaseWaitDlg.progress.setValue(0);
93
94 boolean useChangesets = api.hasChangesetSupport();
95
96 // controls whether or not we try and upload the whole bunch in one go
97 boolean useDiffUploads = Main.pref.getBoolean("osm-server.atomic-upload",
98 "0.6".equals(api.getVersion()));
99
100 // create changeset if required
101 try {
102 if (useChangesets) {
103 // add the last entered comment to the changeset
104 String cmt = "";
105 List<String> history = StringUtils.stringToList(Main.pref.get(UploadAction.HISTORY_KEY), JHistoryComboBox.DELIM);
106 if(history.size() > 0) {
107 cmt = history.get(0);
108 }
109 api.createChangeset(cmt);
110 }
111 } catch (OsmTransferException ex) {
112 dealWithTransferException(ex);
113 return;
114 }
115
116 try {
117 if (useDiffUploads) {
118 // all in one go
119 processed.addAll(api.uploadDiff(list));
120 } else {
121 // upload changes individually (90% of code is for the status display...)
122 NameVisitor v = new NameVisitor();
123 uploadStartTime = System.currentTimeMillis();
124 for (OsmPrimitive osm : list) {
125 osm.visit(v);
126 int progress = Main.pleaseWaitDlg.progress.getValue();
127 String time_left_str = timeLeft(progress, list.size());
128 Main.pleaseWaitDlg.currentAction.setText(
129 tr("{0}% ({1}/{2}), {3} left. Uploading {4}: {5} (id: {6})",
130 Math.round(100.0*progress/list.size()), progress,
131 list.size(), time_left_str, tr(v.className), v.name, osm.id));
132 makeApiRequest(osm);
133 processed.add(osm);
134 Main.pleaseWaitDlg.progress.setValue(progress+1);
135 }
136 }
137 if (useChangesets) api.stopChangeset();
138 } catch (OsmTransferException e) {
139 try {
140 if (useChangesets) api.stopChangeset();
141 } catch (Exception ee) {
142 // ignore nested exception
143 }
144 dealWithTransferException(e);
145 }
146 }
147
148 void makeApiRequest(OsmPrimitive osm) throws OsmTransferException {
149 if (osm.deleted) {
150 api.deletePrimitive(osm);
151 } else if (osm.id == 0) {
152 api.createPrimitive(osm);
153 } else {
154 api.modifyPrimitive(osm);
155 }
156 }
157
158 private void dealWithTransferException (OsmTransferException e) {
159 if (e instanceof OsmTransferCancelledException) {
160 // ignore - don't bother the user with yet another message that he
161 // has successfully cancelled the data upload
162 //
163 return;
164 }
165
166 JOptionPane.showMessageDialog(Main.parent,
167 /* tr("Error during upload: ") + */ e.getMessage());
168 }
169}
Note: See TracBrowser for help on using the repository browser.