001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.io;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.io.IOException;
007import java.util.ArrayList;
008import java.util.Collection;
009import java.util.List;
010import java.util.Optional;
011
012import javax.swing.SwingUtilities;
013
014import org.openstreetmap.josm.data.osm.Changeset;
015import org.openstreetmap.josm.data.osm.ChangesetCache;
016import org.openstreetmap.josm.gui.ExceptionDialogUtil;
017import org.openstreetmap.josm.gui.PleaseWaitRunnable;
018import org.openstreetmap.josm.io.OsmApi;
019import org.openstreetmap.josm.io.OsmTransferException;
020import org.xml.sax.SAXException;
021
022/**
023 * A task for closing a collection of changesets.
024 *
025 */
026public class CloseChangesetTask extends PleaseWaitRunnable {
027    private boolean canceled;
028    private Exception lastException;
029    private final Collection<Changeset> changesets;
030    private final List<Changeset> closedChangesets;
031
032    /**
033     * Closes all changesets in <code>changesets</code> if they are not null, if they
034     * are still open and if they have an id &gt; 0. Other changesets in the collection
035     * are ignored.
036     *
037     * @param changesets  the collection of changesets. Empty collection assumes, if null.
038     */
039    public CloseChangesetTask(Collection<Changeset> changesets) {
040        super(tr("Closing changeset"), false /* don't ignore exceptions */);
041        this.changesets = Optional.ofNullable(changesets).orElseGet(ArrayList::new);
042        this.closedChangesets = new ArrayList<>();
043    }
044
045    @Override
046    protected void cancel() {
047        this.canceled = true;
048        OsmApi.getOsmApi().cancel();
049    }
050
051    @Override
052    protected void finish() {
053        if (canceled)
054            return;
055        if (lastException != null) {
056            ExceptionDialogUtil.explainException(lastException);
057        }
058        SwingUtilities.invokeLater(() -> ChangesetCache.getInstance().update(closedChangesets));
059    }
060
061    @Override
062    protected void realRun() throws SAXException, IOException, OsmTransferException {
063        try {
064            for (Changeset cs: changesets) {
065                if (canceled) return;
066                if (cs == null || cs.getId() <= 0 || !cs.isOpen()) {
067                    continue;
068                }
069                getProgressMonitor().subTask(tr("Closing changeset {0}", cs.getId()));
070                OsmApi.getOsmApi().closeChangeset(cs, getProgressMonitor().createSubTaskMonitor(1, false));
071                closedChangesets.add(cs);
072            }
073        } catch (OsmTransferException e) {
074            if (canceled)
075                return;
076            lastException = e;
077        }
078    }
079}