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

Last change on this file since 12636 was 12636, checked in by Don-vip, 15 months ago

see #15182 - deprecate Main.getLayerManager(). Replacement: gui.MainApplication.getLayerManager()

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