001    // License: GPL. For details, see LICENSE file.
002    package org.openstreetmap.josm.actions;
003    
004    import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
005    import static org.openstreetmap.josm.tools.I18n.tr;
006    
007    import java.awt.event.ActionEvent;
008    import java.awt.event.KeyEvent;
009    import java.io.IOException;
010    import java.util.Collection;
011    import java.util.List;
012    
013    import javax.swing.JOptionPane;
014    import javax.swing.SwingUtilities;
015    
016    import org.openstreetmap.josm.Main;
017    import org.openstreetmap.josm.data.osm.Changeset;
018    import org.openstreetmap.josm.data.osm.ChangesetCache;
019    import org.openstreetmap.josm.data.osm.UserInfo;
020    import org.openstreetmap.josm.gui.ExceptionDialogUtil;
021    import org.openstreetmap.josm.gui.PleaseWaitRunnable;
022    import org.openstreetmap.josm.gui.io.CloseChangesetDialog;
023    import org.openstreetmap.josm.gui.io.CloseChangesetTask;
024    import org.openstreetmap.josm.io.ChangesetQuery;
025    import org.openstreetmap.josm.io.OsmServerChangesetReader;
026    import org.openstreetmap.josm.io.OsmServerUserInfoReader;
027    import org.openstreetmap.josm.io.OsmTransferException;
028    import org.openstreetmap.josm.tools.Shortcut;
029    import org.xml.sax.SAXException;
030    
031    public class CloseChangesetAction extends JosmAction{
032    
033        public CloseChangesetAction() {
034            super(tr("Close open changesets"),
035                "closechangeset",
036                tr("Closes open changesets"),
037                Shortcut.registerShortcut("system:closechangeset",
038                    tr("File: {0}", tr("Closes open changesets")),
039                    KeyEvent.VK_Q, Shortcut.ALT_CTRL),
040                true
041            );
042            putValue("help", ht("/Action/CloseChangeset"));
043    
044        }
045        public void actionPerformed(ActionEvent e) {
046            Main.worker.submit(new DownloadOpenChangesetsTask());
047        }
048    
049        protected void onPostDownloadOpenChangesets() {
050            List<Changeset> openChangesets = ChangesetCache.getInstance().getOpenChangesets();
051            if (openChangesets.isEmpty()) {
052                JOptionPane.showMessageDialog(
053                        Main.parent,
054                        tr("There are no open changesets"),
055                        tr("No open changesets"),
056                        JOptionPane.INFORMATION_MESSAGE
057                );
058                return;
059            }
060    
061            CloseChangesetDialog dialog = new CloseChangesetDialog();
062            dialog.setChangesets(openChangesets);
063            dialog.setVisible(true);
064            if (dialog.isCanceled())
065                return;
066    
067            Collection<Changeset> changesetsToClose = dialog.getSelectedChangesets();
068            CloseChangesetTask closeChangesetTask = new CloseChangesetTask(changesetsToClose);
069            Main.worker.submit(closeChangesetTask);
070        }
071    
072        private class DownloadOpenChangesetsTask extends PleaseWaitRunnable {
073    
074            private boolean canceled;
075            private OsmServerChangesetReader reader;
076            private List<Changeset> changesets;
077            private Exception lastException;
078            private UserInfo userInfo;
079    
080            /**
081             *
082             * @param model provides the user id of the current user and accepts the changesets
083             * after download
084             */
085            public DownloadOpenChangesetsTask() {
086                super(tr("Downloading open changesets ...", false /* don't ignore exceptions */));
087            }
088    
089            @Override
090            protected void cancel() {
091                this.canceled = true;
092                reader.cancel();
093            }
094    
095            @Override
096            protected void finish() {
097                SwingUtilities.invokeLater(
098                        new Runnable() {
099                            public void run() {
100                                if (lastException != null) {
101                                    ExceptionDialogUtil.explainException(lastException);
102                                }
103                                ChangesetCache.getInstance().update(changesets);
104                                if (!canceled && lastException == null) {
105                                    onPostDownloadOpenChangesets();
106                                }
107                            }
108                        }
109                );
110            }
111    
112            /**
113             * Fetch the user info from the server. This is necessary if we don't know
114             * the users id yet
115             *
116             * @return the user info
117             * @throws OsmTransferException thrown in case of any communication exception
118             */
119            protected UserInfo fetchUserInfo() throws OsmTransferException {
120                OsmServerUserInfoReader reader = new OsmServerUserInfoReader();
121                return reader.fetchUserInfo(getProgressMonitor().createSubTaskMonitor(1, false));
122            }
123    
124            @Override
125            protected void realRun() throws SAXException, IOException, OsmTransferException {
126                try {
127                    userInfo = fetchUserInfo();
128                    if (canceled)
129                        return;
130                    reader = new OsmServerChangesetReader();
131                    ChangesetQuery query = new ChangesetQuery().forUser(userInfo.getId()).beingOpen(true);
132                    changesets = reader.queryChangesets(
133                            query,
134                            getProgressMonitor().createSubTaskMonitor(1, false /* not internal */)
135                    );
136                } catch(Exception e) {
137                    if (canceled)
138                        return;
139                    lastException = e;
140                }
141            }
142    
143            public boolean isCanceled() {
144                return canceled;
145            }
146    
147            public Exception getLastException() {
148                return lastException;
149            }
150        }
151    }