source: josm/trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadReferrersTask.java@ 11809

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

see #11390 - sonar - squid:S1604 - Java 8: Anonymous inner classes containing only one method should become lambdas

  • Property svn:eol-style set to native
File size: 7.5 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.actions.downloadtasks;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5import static org.openstreetmap.josm.tools.I18n.trn;
6
7import java.io.IOException;
8import java.text.MessageFormat;
9import java.util.Collection;
10import java.util.HashMap;
11import java.util.HashSet;
12import java.util.Map;
13import java.util.Map.Entry;
14import java.util.Set;
15
16import javax.swing.JOptionPane;
17import javax.swing.SwingUtilities;
18
19import org.openstreetmap.josm.Main;
20import org.openstreetmap.josm.data.osm.DataSet;
21import org.openstreetmap.josm.data.osm.DataSetMerger;
22import org.openstreetmap.josm.data.osm.Node;
23import org.openstreetmap.josm.data.osm.OsmPrimitive;
24import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
25import org.openstreetmap.josm.data.osm.PrimitiveId;
26import org.openstreetmap.josm.data.osm.Way;
27import org.openstreetmap.josm.gui.PleaseWaitRunnable;
28import org.openstreetmap.josm.gui.layer.OsmDataLayer;
29import org.openstreetmap.josm.gui.progress.ProgressMonitor;
30import org.openstreetmap.josm.io.MultiFetchServerObjectReader;
31import org.openstreetmap.josm.io.OsmServerBackreferenceReader;
32import org.openstreetmap.josm.io.OsmServerReader;
33import org.openstreetmap.josm.io.OsmTransferException;
34import org.openstreetmap.josm.tools.CheckParameterUtil;
35import org.openstreetmap.josm.tools.ExceptionUtil;
36import org.xml.sax.SAXException;
37
38/**
39 * The asynchronous task for downloading referring primitives
40 * @since 2923
41 */
42public class DownloadReferrersTask extends PleaseWaitRunnable {
43 private boolean canceled;
44 private Exception lastException;
45 private OsmServerReader reader;
46 /** the target layer */
47 private final OsmDataLayer targetLayer;
48 /** the collection of child primitives */
49 private final Map<Long, OsmPrimitiveType> children;
50 /** the parents */
51 private final DataSet parents;
52
53 /**
54 * constructor
55 *
56 * @param targetLayer the target layer for the downloaded primitives. Must not be null.
57 * @param children the collection of child primitives for which parents are to be downloaded
58 */
59 public DownloadReferrersTask(OsmDataLayer targetLayer, Collection<OsmPrimitive> children) {
60 super("Download referrers", false /* don't ignore exception*/);
61 CheckParameterUtil.ensureParameterNotNull(targetLayer, "targetLayer");
62 canceled = false;
63 this.children = new HashMap<>();
64 if (children != null) {
65 for (OsmPrimitive p: children) {
66 if (!p.isNew()) {
67 this.children.put(p.getId(), OsmPrimitiveType.from(p));
68 }
69 }
70 }
71 this.targetLayer = targetLayer;
72 parents = new DataSet();
73 }
74
75 /**
76 * constructor
77 *
78 * @param targetLayer the target layer. Must not be null.
79 * @param primitiveId a PrimitiveId object.
80 * @param progressMonitor ProgressMonitor to use or null to create a new one.
81 * @throws IllegalArgumentException if id &lt;= 0
82 * @throws IllegalArgumentException if targetLayer == null
83 */
84 public DownloadReferrersTask(OsmDataLayer targetLayer, PrimitiveId primitiveId,
85 ProgressMonitor progressMonitor) {
86 super("Download referrers", progressMonitor, false /* don't ignore exception*/);
87 CheckParameterUtil.ensureParameterNotNull(targetLayer, "targetLayer");
88 if (primitiveId.isNew())
89 throw new IllegalArgumentException(MessageFormat.format(
90 "Cannot download referrers for new primitives (ID {0})", primitiveId.getUniqueId()));
91 canceled = false;
92 this.children = new HashMap<>();
93 this.children.put(primitiveId.getUniqueId(), primitiveId.getType());
94 this.targetLayer = targetLayer;
95 parents = new DataSet();
96 }
97
98 @Override
99 protected void cancel() {
100 canceled = true;
101 synchronized (this) {
102 if (reader != null) {
103 reader.cancel();
104 }
105 }
106 }
107
108 @Override
109 protected void finish() {
110 if (canceled)
111 return;
112 if (lastException != null) {
113 ExceptionUtil.explainException(lastException);
114 return;
115 }
116
117 DataSetMerger visitor = new DataSetMerger(targetLayer.data, parents);
118 visitor.merge();
119 SwingUtilities.invokeLater(targetLayer::onPostDownloadFromServer);
120 if (visitor.getConflicts().isEmpty())
121 return;
122 targetLayer.getConflicts().add(visitor.getConflicts());
123 JOptionPane.showMessageDialog(
124 Main.parent,
125 trn("There was {0} conflict during import.",
126 "There were {0} conflicts during import.",
127 visitor.getConflicts().size(),
128 visitor.getConflicts().size()
129 ),
130 trn("Conflict during download", "Conflicts during download", visitor.getConflicts().size()),
131 JOptionPane.WARNING_MESSAGE
132 );
133 Main.map.conflictDialog.unfurlDialog();
134 Main.map.repaint();
135 }
136
137 protected void downloadParents(long id, OsmPrimitiveType type, ProgressMonitor progressMonitor) throws OsmTransferException {
138 reader = new OsmServerBackreferenceReader(id, type);
139 DataSet ds = reader.parseOsm(progressMonitor.createSubTaskMonitor(1, false));
140 synchronized (this) { // avoid race condition in cancel()
141 reader = null;
142 }
143 Collection<Way> ways = ds.getWays();
144
145 DataSetMerger merger;
146 if (!ways.isEmpty()) {
147 Set<Node> nodes = new HashSet<>();
148 for (Way w: ways) {
149 // Ensure each node is only listed once
150 nodes.addAll(w.getNodes());
151 }
152 // Don't retrieve any nodes we've already grabbed
153 nodes.removeAll(targetLayer.data.getNodes());
154 if (!nodes.isEmpty()) {
155 reader = MultiFetchServerObjectReader.create();
156 ((MultiFetchServerObjectReader) reader).append(nodes);
157 DataSet wayNodes = reader.parseOsm(progressMonitor.createSubTaskMonitor(1, false));
158 synchronized (this) { // avoid race condition in cancel()
159 reader = null;
160 }
161 merger = new DataSetMerger(ds, wayNodes);
162 merger.merge();
163 }
164 }
165 merger = new DataSetMerger(parents, ds);
166 merger.merge();
167 }
168
169 @Override
170 protected void realRun() throws SAXException, IOException, OsmTransferException {
171 try {
172 progressMonitor.setTicksCount(children.size());
173 int i = 1;
174 for (Entry<Long, OsmPrimitiveType> entry: children.entrySet()) {
175 if (canceled)
176 return;
177 String msg;
178 switch(entry.getValue()) {
179 case NODE: msg = tr("({0}/{1}) Loading parents of node {2}", i+1, children.size(), entry.getKey()); break;
180 case WAY: msg = tr("({0}/{1}) Loading parents of way {2}", i+1, children.size(), entry.getKey()); break;
181 case RELATION: msg = tr("({0}/{1}) Loading parents of relation {2}", i+1, children.size(), entry.getKey()); break;
182 default: throw new AssertionError();
183 }
184 progressMonitor.subTask(msg);
185 downloadParents(entry.getKey(), entry.getValue(), progressMonitor);
186 i++;
187 }
188 } catch (OsmTransferException e) {
189 if (canceled)
190 return;
191 lastException = e;
192 }
193 }
194}
Note: See TracBrowser for help on using the repository browser.