// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.gui.io;
import static org.openstreetmap.josm.tools.I18n.tr;
import java.awt.Component;
import java.io.IOException;
import java.util.List;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import org.openstreetmap.josm.Main;
import org.openstreetmap.josm.data.osm.Changeset;
import org.openstreetmap.josm.data.osm.ChangesetCache;
import org.openstreetmap.josm.data.osm.UserInfo;
import org.openstreetmap.josm.gui.ExceptionDialogUtil;
import org.openstreetmap.josm.gui.JosmUserIdentityManager;
import org.openstreetmap.josm.gui.PleaseWaitRunnable;
import org.openstreetmap.josm.io.ChangesetQuery;
import org.openstreetmap.josm.io.OsmServerChangesetReader;
import org.openstreetmap.josm.io.OsmServerUserInfoReader;
import org.openstreetmap.josm.io.OsmTransferException;
import org.xml.sax.SAXException;
/**
* This is a task for downloading the open changesets of the current user
* from the OSM server.
*/
public class DownloadOpenChangesetsTask extends PleaseWaitRunnable {
private boolean canceled;
private OsmServerChangesetReader reader;
private List<Changeset> changesets;
private Exception lastException;
private Component parent;
/**
* Constructs the task
* @param parent is a component to show error messages
*/
public DownloadOpenChangesetsTask(Component parent) {
super(parent, tr("Downloading open changesets ..."), false /* don't ignore exceptions */);
this.parent = parent;
}
@Override
protected void cancel() {
this.canceled = true;
synchronized(this) {
if (reader != null) {
reader.cancel();
}
}
}
@Override
protected void finish() {
if (JosmUserIdentityManager.getInstance().isAnonymous()) {
JOptionPane.showMessageDialog(
JOptionPane.getFrameForComponent(parent),
"<html>" + tr("Could not retrieve the list of your open changesets because<br>"
+ "JOSM does not know your identity.<br>"
+ "You have either chosen to work anonymously or you are not entitled<br>"
+ "to know the identity of the user on whose behalf you are working.")
+ "</html>",
tr("Missing user identity"),
JOptionPane.ERROR_MESSAGE
);
return;
}
if (canceled)return;
if (lastException != null) {
ExceptionDialogUtil.explainException(lastException);
return;
}
if (changesets.isEmpty()) {
JOptionPane.showMessageDialog(
Main.parent,
tr("There are no open changesets"),
tr("No open changesets"),
JOptionPane.INFORMATION_MESSAGE
);
return;
}
SwingUtilities.invokeLater(
new Runnable() {
@Override public void run() {
ChangesetCache.getInstance().update(changesets);
}
}
);
}
/**
* Refreshes the user info from the server. This is necessary if we don't know
* the users id yet.
*
*/
protected void refreshUserIdentity(){
JosmUserIdentityManager im = JosmUserIdentityManager.getInstance();
try {
OsmServerUserInfoReader infoReader = new OsmServerUserInfoReader();
UserInfo info = infoReader.fetchUserInfo(getProgressMonitor().createSubTaskMonitor(1, false));
im.setFullyIdentified(info.getDisplayName(), info);
} catch(OsmTransferException e) {
// retrieving the user info can fail if the current user is not authorised to
// retrieve it, i.e. if he is working with an OAuth Access Token which doesn't
// have the respective privileges or if he didn't or he can't authenticate with
// a username/password-pair.
//
// Downgrade your knowlege about its identity if we've assumed that he was fully
// identified. Otherwise, if he is anonymous or partially identified, keep our level
// of knowlege.
//
if (im.isFullyIdentified()) {
im.setPartiallyIdentified(im.getUserName());
}
Main.warn(tr("Failed to retrieve user infos for the current JOSM user. Exception was: {0}", e.toString()));
}
}
@Override
protected void realRun() throws SAXException, IOException, OsmTransferException {
try {
JosmUserIdentityManager im = JosmUserIdentityManager.getInstance();
if (im.isAnonymous()) {
refreshUserIdentity();
} else if (im.isFullyIdentified()){
// do nothing
} else if (im.isPartiallyIdentified()) {
refreshUserIdentity();
}
if (canceled)return;
synchronized(this) {
reader = new OsmServerChangesetReader();
}
ChangesetQuery query = new ChangesetQuery().beingOpen(true);
if (im.isAnonymous())
// we still don't know anything about the current user. Can't retrieve
// its changesets
return;
else if (im.isFullyIdentified()) {
query = query.forUser(im.getUserId());
} else {
// we only know the users name, not its id. Nevermind, try to read
// its open changesets anyway.
//
query = query.forUser(im.getUserName());
}
changesets = reader.queryChangesets(
query,
getProgressMonitor().createSubTaskMonitor(1, false /* not internal */)
);
} catch(Exception e) {
if (canceled)
return;
lastException = e;
}
}
public boolean isCanceled() {
return canceled;
}
}