source: josm/trunk/src/org/openstreetmap/josm/gui/dialogs/relation/DownloadRelationMemberTask.java @ 13486

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

fix #8039, see #10456 - fix bugs with non-downloadable layers

  • Property svn:eol-style set to native
File size: 5.9 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.dialogs.relation;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5import static org.openstreetmap.josm.tools.I18n.trn;
6
7import java.awt.Dialog;
8import java.io.IOException;
9import java.util.Collection;
10import java.util.HashSet;
11import java.util.Objects;
12import java.util.Set;
13
14import javax.swing.SwingUtilities;
15
16import org.openstreetmap.josm.data.osm.DataSet;
17import org.openstreetmap.josm.data.osm.DefaultNameFormatter;
18import org.openstreetmap.josm.data.osm.OsmPrimitive;
19import org.openstreetmap.josm.data.osm.Relation;
20import org.openstreetmap.josm.gui.ExceptionDialogUtil;
21import org.openstreetmap.josm.gui.MainApplication;
22import org.openstreetmap.josm.gui.PleaseWaitRunnable;
23import org.openstreetmap.josm.gui.layer.OsmDataLayer;
24import org.openstreetmap.josm.gui.progress.ProgressMonitor;
25import org.openstreetmap.josm.gui.progress.swing.PleaseWaitProgressMonitor;
26import org.openstreetmap.josm.io.MultiFetchServerObjectReader;
27import org.openstreetmap.josm.io.OsmTransferException;
28import org.openstreetmap.josm.tools.Logging;
29import org.xml.sax.SAXException;
30
31/**
32 * The asynchronous task for downloading relation members.
33 * @since 2563
34 */
35public class DownloadRelationMemberTask extends PleaseWaitRunnable {
36    private boolean canceled;
37    private Exception lastException;
38    private final Set<Relation> parents = new HashSet<>();
39    private final Collection<OsmPrimitive> children;
40    private final OsmDataLayer curLayer;
41    private MultiFetchServerObjectReader objectReader;
42
43    public DownloadRelationMemberTask(Relation parent, Collection<OsmPrimitive> children, OsmDataLayer curLayer, Dialog dialog) {
44        super(tr("Download relation members"), new PleaseWaitProgressMonitor(dialog), false /* don't ignore exception */);
45        if (parent != null)
46            this.parents.add(parent);
47        this.children = Objects.requireNonNull(children);
48        this.curLayer = Objects.requireNonNull(curLayer);
49        checkLayer();
50    }
51
52    public DownloadRelationMemberTask(Relation parent, Collection<OsmPrimitive> children, OsmDataLayer curLayer) {
53        super(tr("Download relation members"), false /* don't ignore exception */);
54        if (parent != null)
55            this.parents.add(parent);
56        this.children = Objects.requireNonNull(children);
57        this.curLayer = Objects.requireNonNull(curLayer);
58        checkLayer();
59    }
60
61    /**
62     * Creates a download task for downloading the child primitives {@code children} for all parent
63     * relations in {@code parents}.
64     *
65     * @param parents the collection of parent relations
66     * @param children the collection of child primitives to download
67     * @param curLayer the current OSM layer
68     */
69    public DownloadRelationMemberTask(Collection<Relation> parents, Collection<OsmPrimitive> children, OsmDataLayer curLayer) {
70        super(tr("Download relation members"), false /* don't ignore exception */);
71        this.parents.addAll(parents);
72        this.children = Objects.requireNonNull(children);
73        this.curLayer = Objects.requireNonNull(curLayer);
74        checkLayer();
75    }
76
77    private void checkLayer() {
78        if (!curLayer.isDownloadable()) {
79            throw new IllegalArgumentException("Non-downloadable layer: " + curLayer);
80        }
81    }
82
83    @Override
84    protected void cancel() {
85        canceled = true;
86        synchronized (this) {
87            if (objectReader != null) {
88                objectReader.cancel();
89            }
90        }
91    }
92
93    @Override
94    protected void finish() {
95        MainApplication.getMap().repaint();
96        if (canceled)
97            return;
98        if (lastException != null) {
99            ExceptionDialogUtil.explainException(lastException);
100        }
101    }
102
103    protected String buildDownloadFeedbackMessage() {
104        if (parents.isEmpty()) {
105            return trn("Downloading {0} incomplete object",
106                    "Downloading {0} incomplete objects",
107                    children.size(),
108                    children.size());
109        } else if (parents.size() == 1) {
110            Relation parent = parents.iterator().next();
111            return trn("Downloading {0} incomplete child of relation ''{1}''",
112                    "Downloading {0} incomplete children of relation ''{1}''",
113                    children.size(),
114                    children.size(),
115                    parent.getDisplayName(DefaultNameFormatter.getInstance()));
116        } else {
117            return trn("Downloading {0} incomplete child of {1} parent relations",
118                    "Downloading {0} incomplete children of {1} parent relations",
119                    children.size(),
120                    children.size(),
121                    parents.size());
122        }
123    }
124
125    @Override
126    protected void realRun() throws SAXException, IOException, OsmTransferException {
127        try {
128            synchronized (this) {
129                if (canceled) return;
130                objectReader = MultiFetchServerObjectReader.create();
131            }
132            objectReader.append(children);
133            progressMonitor.indeterminateSubTask(
134                    buildDownloadFeedbackMessage()
135            );
136            final DataSet dataSet = objectReader.parseOsm(progressMonitor
137                    .createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false));
138            if (dataSet == null)
139                return;
140            dataSet.deleteInvisible();
141            synchronized (this) {
142                if (canceled) return;
143                objectReader = null;
144            }
145
146            SwingUtilities.invokeLater(() -> {
147                curLayer.mergeFrom(dataSet);
148                curLayer.onPostDownloadFromServer();
149            });
150        } catch (OsmTransferException e) {
151            if (canceled) {
152                Logging.warn(tr("Ignoring exception because task was canceled. Exception: {0}", e.toString()));
153                return;
154            }
155            lastException = e;
156        }
157    }
158}
Note: See TracBrowser for help on using the repository browser.