source: josm/trunk/src/org/openstreetmap/josm/gui/io/DownloadPrimitivesWithReferrersTask.java@ 10436

Last change on this file since 10436 was 10436, checked in by Don-vip, 8 years ago

see #13001 - replace calls to Main.main.[add|remove]Layer by Main.getLayerManager().[add|remove]Layer

  • Property svn:eol-style set to native
File size: 9.0 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.io;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5import static org.openstreetmap.josm.tools.I18n.trn;
6
7import java.awt.Font;
8import java.awt.GridBagLayout;
9import java.io.IOException;
10import java.util.ArrayList;
11import java.util.HashSet;
12import java.util.List;
13import java.util.Set;
14
15import javax.swing.JLabel;
16import javax.swing.JOptionPane;
17import javax.swing.JPanel;
18import javax.swing.JScrollPane;
19
20import org.openstreetmap.josm.Main;
21import org.openstreetmap.josm.actions.downloadtasks.DownloadReferrersTask;
22import org.openstreetmap.josm.data.osm.DataSet;
23import org.openstreetmap.josm.data.osm.OsmPrimitive;
24import org.openstreetmap.josm.data.osm.PrimitiveId;
25import org.openstreetmap.josm.gui.ExtendedDialog;
26import org.openstreetmap.josm.gui.PleaseWaitRunnable;
27import org.openstreetmap.josm.gui.layer.OsmDataLayer;
28import org.openstreetmap.josm.gui.progress.ProgressMonitor;
29import org.openstreetmap.josm.gui.util.GuiHelper;
30import org.openstreetmap.josm.gui.widgets.HtmlPanel;
31import org.openstreetmap.josm.gui.widgets.JosmTextArea;
32import org.openstreetmap.josm.io.OsmTransferException;
33import org.openstreetmap.josm.tools.GBC;
34import org.openstreetmap.josm.tools.Utils;
35import org.xml.sax.SAXException;
36
37/**
38 * Task for downloading a set of primitives with all referrers.
39 */
40public class DownloadPrimitivesWithReferrersTask extends PleaseWaitRunnable {
41 /** If true download into a new layer */
42 private final boolean newLayer;
43 /** List of primitives id to download */
44 private final List<PrimitiveId> ids;
45 /** If true, download members for relation */
46 private final boolean full;
47 /** If true, download also referrers */
48 private final boolean downloadReferrers;
49
50 /** Temporary layer where downloaded primitives are put */
51 private final OsmDataLayer tmpLayer;
52 /** Reference to the task that download requested primitives */
53 private DownloadPrimitivesTask mainTask;
54 /** Flag indicated that user ask for cancel this task */
55 private boolean canceled;
56 /** Reference to the task currently running */
57 private PleaseWaitRunnable currentTask;
58
59 /**
60 * Constructor
61 *
62 * @param newLayer if the data should be downloaded into a new layer
63 * @param ids List of primitive id to download
64 * @param downloadReferrers if the referrers of the object should be downloaded as well,
65 * i.e., parent relations, and for nodes, additionally, parent ways
66 * @param full if the members of a relation should be downloaded as well
67 * @param newLayerName the name to use for the new layer, can be {@code null}.
68 * @param monitor ProgressMonitor to use, or null to create a new one
69 */
70 public DownloadPrimitivesWithReferrersTask(boolean newLayer, List<PrimitiveId> ids, boolean downloadReferrers,
71 boolean full, String newLayerName, ProgressMonitor monitor) {
72 super(tr("Download objects"), monitor, false);
73 this.ids = ids;
74 this.downloadReferrers = downloadReferrers;
75 this.full = full;
76 this.newLayer = newLayer;
77 // All downloaded primitives are put in a tmpLayer
78 tmpLayer = new OsmDataLayer(new DataSet(), newLayerName != null ? newLayerName : OsmDataLayer.createNewName(), null);
79 }
80
81 /**
82 * Cancel recursively the task. Do not call directly
83 * @see DownloadPrimitivesWithReferrersTask#operationCanceled()
84 */
85 @Override
86 protected void cancel() {
87 synchronized (this) {
88 canceled = true;
89 if (currentTask != null)
90 currentTask.operationCanceled();
91 }
92 }
93
94 @Override
95 protected void realRun() throws SAXException, IOException, OsmTransferException {
96 getProgressMonitor().setTicksCount(ids.size()+1);
97 // First, download primitives
98 mainTask = new DownloadPrimitivesTask(tmpLayer, ids, full, getProgressMonitor().createSubTaskMonitor(1, false));
99 synchronized (this) {
100 currentTask = mainTask;
101 if (canceled) {
102 currentTask = null;
103 return;
104 }
105 }
106 currentTask.run();
107 // Then, download referrers for each primitive
108 if (downloadReferrers)
109 for (PrimitiveId id : ids) {
110 synchronized (this) {
111 if (canceled) {
112 currentTask = null;
113 return;
114 }
115 currentTask = new DownloadReferrersTask(
116 tmpLayer, id, getProgressMonitor().createSubTaskMonitor(1, false));
117 }
118 currentTask.run();
119 }
120 currentTask = null;
121 }
122
123 @Override
124 protected void finish() {
125 synchronized (this) {
126 if (canceled)
127 return;
128 }
129
130 // Append downloaded data to JOSM
131 OsmDataLayer layer = Main.getLayerManager().getEditLayer();
132 if (layer == null || this.newLayer)
133 Main.getLayerManager().addLayer(tmpLayer);
134 else
135 layer.mergeFrom(tmpLayer);
136
137 // Warm about missing primitives
138 final Set<PrimitiveId> errs = mainTask.getMissingPrimitives();
139 if (errs != null && !errs.isEmpty())
140 GuiHelper.runInEDTAndWait(new Runnable() {
141 @Override
142 public void run() {
143 reportProblemDialog(errs,
144 trn("Object could not be downloaded", "Some objects could not be downloaded", errs.size()),
145 trn("One object could not be downloaded.<br>",
146 "{0} objects could not be downloaded.<br>",
147 errs.size(),
148 errs.size())
149 + tr("The server replied with response code 404.<br>"
150 + "This usually means, the server does not know an object with the requested id."),
151 tr("missing objects:"),
152 JOptionPane.ERROR_MESSAGE
153 ).showDialog();
154 }
155 });
156
157 // Warm about deleted primitives
158 final Set<PrimitiveId> del = new HashSet<>();
159 DataSet ds = Main.main.getCurrentDataSet();
160 for (PrimitiveId id : ids) {
161 OsmPrimitive osm = ds.getPrimitiveById(id);
162 if (osm != null && osm.isDeleted()) {
163 del.add(id);
164 }
165 }
166 if (!del.isEmpty())
167 GuiHelper.runInEDTAndWait(new Runnable() {
168 @Override
169 public void run() {
170 reportProblemDialog(del,
171 trn("Object deleted", "Objects deleted", del.size()),
172 trn(
173 "One downloaded object is deleted.",
174 "{0} downloaded objects are deleted.",
175 del.size(),
176 del.size()),
177 null,
178 JOptionPane.WARNING_MESSAGE
179 ).showDialog();
180 }
181 });
182 }
183
184 /**
185 * Return id of really downloaded primitives.
186 * @return List of primitives id or null if no primitives was downloaded
187 */
188 public List<PrimitiveId> getDownloadedId() {
189 synchronized (this) {
190 if (canceled)
191 return null;
192 }
193 List<PrimitiveId> downloaded = new ArrayList<>(ids);
194 downloaded.removeAll(mainTask.getMissingPrimitives());
195 return downloaded;
196 }
197
198 /**
199 * Dialog for report a problem during download.
200 * @param errs Primitives involved
201 * @param title Title of dialog
202 * @param text Detail message
203 * @param listLabel List of primitives description
204 * @param msgType Type of message, see {@link JOptionPane}
205 * @return The Dialog object
206 */
207 private static ExtendedDialog reportProblemDialog(Set<PrimitiveId> errs,
208 String title, String text, String listLabel, int msgType) {
209 JPanel p = new JPanel(new GridBagLayout());
210 p.add(new HtmlPanel(text), GBC.eop());
211 JosmTextArea txt = new JosmTextArea();
212 if (listLabel != null) {
213 JLabel missing = new JLabel(listLabel);
214 missing.setFont(missing.getFont().deriveFont(Font.PLAIN));
215 missing.setLabelFor(txt);
216 p.add(missing, GBC.eol());
217 }
218 txt.setFont(GuiHelper.getMonospacedFont(txt));
219 txt.setEditable(false);
220 txt.setBackground(p.getBackground());
221 txt.setColumns(40);
222 txt.setRows(1);
223 txt.setText(Utils.join(", ", errs));
224 JScrollPane scroll = new JScrollPane(txt);
225 p.add(scroll, GBC.eop().weight(1.0, 0.0).fill(GBC.HORIZONTAL));
226
227 return new ExtendedDialog(
228 Main.parent,
229 title,
230 new String[] {tr("Ok")})
231 .setButtonIcons(new String[] {"ok"})
232 .setIcon(msgType)
233 .setContent(p, false);
234 }
235}
Note: See TracBrowser for help on using the repository browser.