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

Last change on this file since 8377 was 8338, checked in by Don-vip, 9 years ago

fix squid:S1319 - Declarations should use Java collection interfaces rather than specific implementation classes

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