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

Last change on this file since 1664 was 1664, checked in by Gubaer, 15 years ago

fixed #2656 - JOSM makes excessive capabilities requests to the server

  • Property svn:eol-style set to native
File size: 5.8 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;
9import java.util.logging.Logger;
10
11import org.openstreetmap.josm.Main;
12import org.openstreetmap.josm.actions.UploadAction;
13import org.openstreetmap.josm.data.osm.OsmPrimitive;
14import org.openstreetmap.josm.data.osm.visitor.NameVisitor;
15
16/**
17 * Class that uploads all changes to the osm server.
18 *
19 * This is done like this: - All objects with id = 0 are uploaded as new, except
20 * those in deleted, which are ignored - All objects in deleted list are
21 * deleted. - All remaining objects with modified flag set are updated.
22 */
23public class OsmServerWriter {
24 static private final Logger logger = Logger.getLogger(OsmServerWriter.class.getName());
25
26 /**
27 * This list contains all successfully processed objects. The caller of
28 * upload* has to check this after the call and update its dataset.
29 *
30 * If a server connection error occurs, this may contain fewer entries
31 * than where passed in the list to upload*.
32 */
33 public Collection<OsmPrimitive> processed;
34
35 private OsmApi api = OsmApi.getOsmApi();
36
37 private static final int MSECS_PER_SECOND = 1000;
38 private static final int SECONDS_PER_MINUTE = 60;
39 private static final int MSECS_PER_MINUTE = MSECS_PER_SECOND * SECONDS_PER_MINUTE;
40
41 long uploadStartTime;
42
43 public String timeLeft(int progress, int list_size) {
44 long now = System.currentTimeMillis();
45 long elapsed = now - uploadStartTime;
46 if (elapsed == 0) {
47 elapsed = 1;
48 }
49 float uploads_per_ms = (float)progress / elapsed;
50 float uploads_left = list_size - progress;
51 int ms_left = (int)(uploads_left / uploads_per_ms);
52 int minutes_left = ms_left / MSECS_PER_MINUTE;
53 int seconds_left = (ms_left / MSECS_PER_SECOND) % SECONDS_PER_MINUTE ;
54 String time_left_str = Integer.toString(minutes_left) + ":";
55 if (seconds_left < 10) {
56 time_left_str += "0";
57 }
58 time_left_str += Integer.toString(seconds_left);
59 return time_left_str;
60 }
61
62 /**
63 * retrieves the most recent changeset comment from the preferences
64 *
65 * @return the most recent changeset comment
66 */
67 protected String getChangesetComment() {
68 String cmt = "";
69 List<String> history = new LinkedList<String>(
70 Main.pref.getCollection(UploadAction.HISTORY_KEY, new LinkedList<String>()));
71 if(history.size() > 0) {
72 cmt = history.get(0);
73 }
74 return cmt;
75 }
76
77 /**
78 * Send the dataset to the server.
79 *
80 * @param apiVersion version of the data set
81 * @param primitives list of objects to send
82 */
83 public void uploadOsm(String apiVersion, Collection<OsmPrimitive> primitives) throws OsmTransferException {
84 processed = new LinkedList<OsmPrimitive>();
85
86 // initialize API. Abort upload in case of configuration or network
87 // errors
88 //
89 try {
90 api.initialize();
91 } catch(Exception e) {
92 throw new OsmApiInitializationException(e);
93 }
94
95 Main.pleaseWaitDlg.progress.setMaximum(primitives.size());
96 Main.pleaseWaitDlg.progress.setValue(0);
97
98 // check whether we can use changeset
99 //
100 boolean canUseChangeset = api.hasChangesetSupport();
101 boolean useChangeset = Main.pref.getBoolean("osm-server.atomic-upload", apiVersion.compareTo("0.6")>=0);
102 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));
104 useChangeset = false;
105 }
106
107 if (useChangeset) {
108 // upload everything in one changeset
109 //
110 try {
111 api.createChangeset(getChangesetComment());
112 processed.addAll(api.uploadDiff(primitives));
113 } catch(OsmTransferException e) {
114 throw e;
115 } finally {
116 try {
117 if (canUseChangeset) {
118 api.stopChangeset();
119 }
120 } catch (Exception ee) {
121 // ignore nested exception
122 }
123 }
124 } else {
125 // upload changes individually (90% of code is for the status display...)
126 //
127 NameVisitor v = new NameVisitor();
128 uploadStartTime = System.currentTimeMillis();
129 for (OsmPrimitive osm : primitives) {
130 osm.visit(v);
131 int progress = Main.pleaseWaitDlg.progress.getValue();
132 String time_left_str = timeLeft(progress, primitives.size());
133 Main.pleaseWaitDlg.currentAction.setText(
134 tr("{0}% ({1}/{2}), {3} left. Uploading {4}: {5} (id: {6})",
135 Math.round(100.0*progress/primitives.size()), progress,
136 primitives.size(), time_left_str, tr(v.className), v.name, osm.id));
137 makeApiRequest(osm);
138 processed.add(osm);
139 Main.pleaseWaitDlg.progress.setValue(progress+1);
140 }
141 }
142 }
143
144 void makeApiRequest(OsmPrimitive osm) throws OsmTransferException {
145 if (osm.deleted) {
146 api.deletePrimitive(osm);
147 } else if (osm.id == 0) {
148 api.createPrimitive(osm);
149 } else {
150 api.modifyPrimitive(osm);
151 }
152 }
153
154 public void disconnectActiveConnection() {
155 if (api != null && api.activeConnection != null) {
156 api.activeConnection.disconnect();
157 }
158 }
159}
Note: See TracBrowser for help on using the repository browser.