- Timestamp:
- 2016-04-09T16:08:55+02:00 (9 years ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 8 edited
- 4 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/actions/downloadtasks/AbstractChangesetDownloadTask.java
r10113 r10124 1 1 // License: GPL. For details, see LICENSE file. 2 package org.openstreetmap.josm. gui.dialogs.changeset;2 package org.openstreetmap.josm.actions.downloadtasks; 3 3 4 import java.awt.Component; 5 import java.net.URL; 6 import java.util.HashSet; 4 7 import java.util.Set; 8 import java.util.concurrent.Future; 5 9 10 import org.openstreetmap.josm.Main; 11 import org.openstreetmap.josm.data.Bounds; 6 12 import org.openstreetmap.josm.data.osm.Changeset; 13 import org.openstreetmap.josm.gui.PleaseWaitRunnable; 14 import org.openstreetmap.josm.gui.progress.ProgressMonitor; 15 import org.openstreetmap.josm.io.OsmServerChangesetReader; 7 16 8 public interface ChangesetDownloadTask extends Runnable { 9 Set<Changeset> getDownloadedChangesets(); 17 /** 18 * Common abstract implementation of other changeset download tasks. 19 * @since 10124 20 */ 21 public abstract class AbstractChangesetDownloadTask extends AbstractDownloadTask<Set<Changeset>> { 10 22 11 boolean isCanceled(); 23 abstract class RunnableDownloadTask extends PleaseWaitRunnable { 24 /** the reader object used to read changesets from the API */ 25 protected final OsmServerChangesetReader reader = new OsmServerChangesetReader(); 26 /** the set of downloaded changesets */ 27 protected final Set<Changeset> downloadedChangesets = new HashSet<>(); 28 /** keeps the last exception thrown in the task, if any */ 29 protected Exception lastException; 12 30 13 boolean isFailed(); 31 RunnableDownloadTask(Component parent, String title) { 32 super(parent, title, false /* don't ignore exceptions */); 33 } 34 35 @Override 36 protected void cancel() { 37 setCanceled(true); 38 synchronized (this) { 39 if (reader != null) { 40 reader.cancel(); 41 } 42 } 43 } 44 45 protected final void rememberLastException(Exception e) { 46 lastException = e; 47 setFailed(true); 48 } 49 } 50 51 private RunnableDownloadTask downloadTaskRunnable; 52 53 protected final void setDownloadTask(RunnableDownloadTask downloadTask) { 54 this.downloadTaskRunnable = downloadTask; 55 } 56 57 @Override 58 public final Future<?> download(boolean newLayer, Bounds downloadArea, ProgressMonitor progressMonitor) { 59 return download(); 60 } 61 62 /** 63 * Asynchronously launches the changeset download task. This is equivalent to {@code download(false, null, null)}. 64 * 65 * You can wait for the asynchronous download task to finish by synchronizing on the returned 66 * {@link Future}, but make sure not to freeze up JOSM. Example: 67 * <pre> 68 * Future<?> future = task.download(); 69 * // DON'T run this on the Swing EDT or JOSM will freeze 70 * future.get(); // waits for the dowload task to complete 71 * </pre> 72 * 73 * The following example uses a pattern which is better suited if a task is launched from the Swing EDT: 74 * <pre> 75 * final Future<?> future = task.download(); 76 * Runnable runAfterTask = new Runnable() { 77 * public void run() { 78 * // this is not strictly necessary because of the type of executor service 79 * // Main.worker is initialized with, but it doesn't harm either 80 * // 81 * future.get(); // wait for the download task to complete 82 * doSomethingAfterTheTaskCompleted(); 83 * } 84 * } 85 * Main.worker.submit(runAfterTask); 86 * </pre> 87 * 88 * @return the future representing the asynchronous task 89 */ 90 public final Future<?> download() { 91 return Main.worker.submit(downloadTaskRunnable); 92 } 93 94 @Override 95 public final Future<?> loadUrl(boolean newLayer, String url, ProgressMonitor progressMonitor) { 96 return Main.worker.submit(downloadTaskRunnable); 97 } 98 99 @Override 100 public final void cancel() { 101 downloadTaskRunnable.cancel(); 102 } 103 104 @Override 105 public String getConfirmationMessage(URL url) { 106 return null; 107 } 14 108 } -
trunk/src/org/openstreetmap/josm/actions/downloadtasks/AbstractDownloadTask.java
r9067 r10124 8 8 9 9 /** 10 * Common abstract implementation of other download tasks 10 * Common abstract implementation of other download tasks. 11 11 * @param <T> The downloaded data type 12 12 * @since 2322 … … 18 18 protected T downloadedData; 19 19 20 /** 21 * Constructs a new {@code AbstractDownloadTask}. 22 */ 20 23 public AbstractDownloadTask() { 21 24 errorMessages = new ArrayList<>(); 22 25 } 23 26 27 /** 28 * Determines if the download task has been canceled. 29 * @return {@code true} if the download task has been canceled 30 */ 24 31 public boolean isCanceled() { 25 32 return canceled; 26 33 } 27 34 35 /** 36 * Marks this download task as canceled. 37 * @param canceled {@code true} to mark this download task as canceled 38 */ 28 39 public void setCanceled(boolean canceled) { 29 40 this.canceled = canceled; 30 41 } 31 42 43 /** 44 * Determines if the download task has failed. 45 * @return {@code true} if the download task has failed 46 */ 32 47 public boolean isFailed() { 33 48 return failed; 34 49 } 35 50 51 /** 52 * Marks this download task as failed. 53 * @param failed {@code true} to mark this download task as failed 54 */ 36 55 public void setFailed(boolean failed) { 37 56 this.failed = failed; … … 82 101 } 83 102 84 // Can be overridden for more complex checking logic 103 /** 104 * Determines if the given URL is accepted by {@link #getPatterns}. 105 * Can be overridden for more complex checking logic. 106 * @param url URL to donwload 107 * @return {@code true} if this URL is accepted 108 */ 85 109 public boolean acceptsUrl(String url) { 86 if (url == null) return false; 110 if (url == null) 111 return false; 87 112 for (String p: getPatterns()) { 88 113 if (url.matches(p)) { … … 113 138 @Override 114 139 public boolean acceptsUrl(String url, boolean isRemotecontrol) { 115 if (isRemotecontrol && !isSafeForRemotecontrolRequests()) return false; 140 if (isRemotecontrol && !isSafeForRemotecontrolRequests()) 141 return false; 116 142 return acceptsUrl(url); 117 143 } … … 133 159 return new String[]{}; 134 160 } 135 136 161 } -
trunk/src/org/openstreetmap/josm/actions/downloadtasks/ChangesetContentDownloadTask.java
r10113 r10124 1 1 // License: GPL. For details, see LICENSE file. 2 package org.openstreetmap.josm. gui.dialogs.changeset;2 package org.openstreetmap.josm.actions.downloadtasks; 3 3 4 4 import static org.openstreetmap.josm.tools.I18n.tr; … … 10 10 import java.util.Collection; 11 11 import java.util.Collections; 12 import java.util.HashSet;13 12 import java.util.List; 14 import java.util.Set;15 13 14 import org.openstreetmap.josm.Main; 16 15 import org.openstreetmap.josm.data.osm.Changeset; 17 16 import org.openstreetmap.josm.data.osm.ChangesetCache; 18 17 import org.openstreetmap.josm.data.osm.ChangesetDataSet; 19 18 import org.openstreetmap.josm.gui.ExceptionDialogUtil; 20 import org.openstreetmap.josm.gui.PleaseWaitRunnable;21 import org.openstreetmap.josm.io.OsmServerChangesetReader;22 19 import org.openstreetmap.josm.io.OsmTransferCanceledException; 23 20 import org.openstreetmap.josm.io.OsmTransferException; … … 25 22 26 23 /** 27 * This is an asynchronous task for downloading the changeset content of a collection of 28 * changesets. 29 * 24 * This is an asynchronous task for downloading the changeset content of a collection of changesets. 25 * @since 2689 30 26 */ 31 public class ChangesetContentDownloadTask extends PleaseWaitRunnable implementsChangesetDownloadTask {27 public class ChangesetContentDownloadTask extends AbstractChangesetDownloadTask { 32 28 33 /** the list of changeset ids to download */ 34 private final List<Integer> toDownload = new ArrayList<>(); 35 /** true if the task was canceled */ 36 private boolean canceled; 37 /** keeps the last exception thrown in the task, if any */ 38 private Exception lastException; 39 /** the reader object used to read changesets from the API */ 40 private OsmServerChangesetReader reader; 41 /** the set of downloaded changesets */ 42 private Set<Changeset> downloadedChangesets; 29 private final DownloadTask downloadTask; 43 30 44 /** 45 * Initialize the task with a collection of changeset ids to download 46 * 47 * @param ids the collection of ids. May be null. 48 */ 49 protected void init(Collection<Integer> ids) { 50 if (ids == null) { 51 ids = Collections.emptyList(); 31 class DownloadTask extends RunnableDownloadTask { 32 /** the list of changeset ids to download */ 33 private final List<Integer> toDownload = new ArrayList<>(); 34 35 DownloadTask(Component parent, Collection<Integer> ids) { 36 super(parent, tr("Downloading changeset content")); 37 for (Integer id: ids != null ? ids : Collections.<Integer>emptyList()) { 38 if (id == null || id <= 0) { 39 continue; 40 } 41 toDownload.add(id); 42 } 52 43 } 53 for (Integer id: ids) { 54 if (id == null || id <= 0) { 55 continue; 44 45 /** 46 * Downloads the changeset with id <code>changesetId</code> (only "header" information, no content) 47 * 48 * @param changesetId the changeset id 49 * @throws OsmTransferException if something went wrong 50 */ 51 protected void downloadChangeset(int changesetId) throws OsmTransferException { 52 Changeset cs = reader.readChangeset(changesetId, false, getProgressMonitor().createSubTaskMonitor(0, false)); 53 ChangesetCache.getInstance().update(cs); 54 } 55 56 @Override 57 protected void realRun() throws SAXException, IOException, OsmTransferException { 58 try { 59 getProgressMonitor().setTicksCount(toDownload.size()); 60 int i = 0; 61 for (int id: toDownload) { 62 i++; 63 if (!isAvailableLocally(id)) { 64 getProgressMonitor().setCustomText(tr("({0}/{1}) Downloading changeset {2}...", i, toDownload.size(), id)); 65 downloadChangeset(id); 66 } 67 if (isCanceled()) 68 return; 69 getProgressMonitor().setCustomText(tr("({0}/{1}) Downloading content for changeset {2}...", i, toDownload.size(), id)); 70 ChangesetDataSet ds = reader.downloadChangeset(id, getProgressMonitor().createSubTaskMonitor(0, false)); 71 Changeset cs = ChangesetCache.getInstance().get(id); 72 cs.setContent(ds); 73 ChangesetCache.getInstance().update(cs); 74 downloadedChangesets.add(cs); 75 getProgressMonitor().worked(1); 76 } 77 } catch (OsmTransferCanceledException e) { 78 // the download was canceled by the user. This exception is caught if the user canceled the authentication dialog. 79 setCanceled(true); 80 return; 81 } catch (OsmTransferException e) { 82 if (isCanceled()) 83 return; 84 rememberLastException(e); 56 85 } 57 toDownload.add(id);58 86 } 59 downloadedChangesets = new HashSet<>(); 87 88 @Override 89 protected void finish() { 90 rememberDownloadedData(downloadedChangesets); 91 if (isCanceled()) 92 return; 93 if (lastException != null) { 94 ExceptionDialogUtil.explainException(lastException); 95 } 96 } 60 97 } 61 98 … … 67 104 */ 68 105 public ChangesetContentDownloadTask(int changesetId) { 69 super(tr("Downloading changeset content"), false /* don't ignore exceptions */); 70 if (changesetId <= 0) 71 throw new IllegalArgumentException( 72 MessageFormat.format("Expected integer value > 0 for parameter ''{0}'', got ''{1}''", "changesetId", changesetId)); 73 init(Collections.singleton(changesetId)); 106 this(Main.parent, changesetId); 74 107 } 75 108 76 109 /** 77 110 * Creates a download task for a collection of changesets. null values and id <=0 in 78 * the collection are sil lently discarded.111 * the collection are silently discarded. 79 112 * 80 113 * @param changesetIds the changeset ids. Empty collection assumed, if null. 81 114 */ 82 115 public ChangesetContentDownloadTask(Collection<Integer> changesetIds) { 83 super(tr("Downloading changeset content"), false /* don't ignore exceptions */); 84 init(changesetIds); 116 this(Main.parent, changesetIds); 85 117 } 86 118 … … 94 126 */ 95 127 public ChangesetContentDownloadTask(Component parent, int changesetId) { 96 super(parent, tr("Downloading changeset content"), false /* don't ignore exceptions */);97 128 if (changesetId <= 0) 98 129 throw new IllegalArgumentException( 99 130 MessageFormat.format("Expected integer value > 0 for parameter ''{0}'', got ''{1}''", "changesetId", changesetId)); 100 init(Collections.singleton(changesetId)); 131 downloadTask = new DownloadTask(parent, Collections.singleton(changesetId)); 132 setDownloadTask(downloadTask); 101 133 } 102 134 … … 110 142 */ 111 143 public ChangesetContentDownloadTask(Component parent, Collection<Integer> changesetIds) { 112 super(parent, tr("Downloading changeset content"), false /* don't ignore exceptions */);113 init(changesetIds);144 downloadTask = new DownloadTask(parent, changesetIds); 145 setDownloadTask(downloadTask); 114 146 } 115 147 … … 122 154 * id <code>changesetId</code> 123 155 */ 124 protected boolean isAvailableLocally(int changesetId) {156 protected static boolean isAvailableLocally(int changesetId) { 125 157 return ChangesetCache.getInstance().get(changesetId) != null; 126 158 } 127 128 /**129 * Downloads the changeset with id <code>changesetId</code> (only "header"130 * information, no content)131 *132 * @param changesetId the changeset id133 * @throws OsmTransferException if something went wrong134 */135 protected void downloadChangeset(int changesetId) throws OsmTransferException {136 synchronized (this) {137 reader = new OsmServerChangesetReader();138 }139 Changeset cs = reader.readChangeset(changesetId, false, getProgressMonitor().createSubTaskMonitor(0, false));140 synchronized (this) {141 reader = null;142 }143 ChangesetCache.getInstance().update(cs);144 }145 146 @Override147 protected void cancel() {148 canceled = true;149 synchronized (this) {150 if (reader != null) {151 reader.cancel();152 }153 }154 }155 156 @Override157 protected void finish() {158 if (canceled) return;159 if (lastException != null) {160 ExceptionDialogUtil.explainException(lastException);161 }162 }163 164 @Override165 protected void realRun() throws SAXException, IOException, OsmTransferException {166 try {167 getProgressMonitor().setTicksCount(toDownload.size());168 int i = 0;169 for (int id: toDownload) {170 i++;171 if (!isAvailableLocally(id)) {172 getProgressMonitor().setCustomText(tr("({0}/{1}) Downloading changeset {2}...", i, toDownload.size(), id));173 downloadChangeset(id);174 }175 if (canceled) return;176 synchronized (this) {177 reader = new OsmServerChangesetReader();178 }179 getProgressMonitor().setCustomText(tr("({0}/{1}) Downloading content for changeset {2}...", i, toDownload.size(), id));180 ChangesetDataSet ds = reader.downloadChangeset(id, getProgressMonitor().createSubTaskMonitor(0, false));181 synchronized (this) {182 reader = null;183 }184 Changeset cs = ChangesetCache.getInstance().get(id);185 cs.setContent(ds);186 ChangesetCache.getInstance().update(cs);187 downloadedChangesets.add(cs);188 getProgressMonitor().worked(1);189 }190 } catch (OsmTransferCanceledException e) {191 // the download was canceled by the user. This exception is caught if the192 // user canceled the authentication dialog.193 //194 canceled = true;195 return;196 } catch (OsmTransferException e) {197 if (canceled)198 return;199 lastException = e;200 }201 }202 203 /* ------------------------------------------------------------------------------- */204 /* interface ChangesetDownloadTask */205 /* ------------------------------------------------------------------------------- */206 @Override207 public Set<Changeset> getDownloadedChangesets() {208 return downloadedChangesets;209 }210 211 @Override212 public boolean isCanceled() {213 return canceled;214 }215 216 @Override217 public boolean isFailed() {218 return lastException != null;219 }220 159 } -
trunk/src/org/openstreetmap/josm/actions/downloadtasks/ChangesetHeaderDownloadTask.java
r10113 r10124 1 1 // License: GPL. For details, see LICENSE file. 2 package org.openstreetmap.josm. gui.dialogs.changeset;2 package org.openstreetmap.josm.actions.downloadtasks; 3 3 4 4 import static org.openstreetmap.josm.tools.I18n.tr; … … 18 18 import org.openstreetmap.josm.data.osm.ChangesetCache; 19 19 import org.openstreetmap.josm.gui.ExceptionDialogUtil; 20 import org.openstreetmap.josm.gui.PleaseWaitRunnable;21 import org.openstreetmap.josm.io.OsmServerChangesetReader;22 20 import org.openstreetmap.josm.io.OsmTransferException; 23 21 import org.openstreetmap.josm.tools.CheckParameterUtil; … … 27 25 28 26 /** 29 * This is an asynchronous task for downloading a collection of changests from the OSM 30 * server. 27 * This is an asynchronous task for downloading a collection of changests from the OSM server. 31 28 * 32 29 * The task only downloads the changeset properties without the changeset content. It 33 30 * updates the global {@link ChangesetCache}. 34 * 31 * @since 2613 35 32 */ 36 public class ChangesetHeaderDownloadTask extends PleaseWaitRunnable implementsChangesetDownloadTask {33 public class ChangesetHeaderDownloadTask extends AbstractChangesetDownloadTask { 37 34 38 /** 39 * Builds a download task from for a collection of changesets. 40 * 41 * Ignores null values and changesets with {@link Changeset#isNew()} == true. 42 * 43 * @param changesets the collection of changesets. Assumes an empty collection if null. 44 * @return the download task 45 */ 46 public static ChangesetHeaderDownloadTask buildTaskForChangesets(Collection<Changeset> changesets) { 47 return buildTaskForChangesets(Main.parent, changesets); 48 } 35 private final DownloadTask downloadTask; 49 36 50 /**51 * Builds a download task from for a collection of changesets.52 *53 * Ignores null values and changesets with {@link Changeset#isNew()} == true.54 *55 * @param parent the parent component relative to which the {@link org.openstreetmap.josm.gui.PleaseWaitDialog} is displayed. 56 * Must not be null.57 * @param changesets the collection of changesets. Assumes an empty collection if null.58 * @return the download task59 * @throws IllegalArgumentException if parent is null60 */61 public static ChangesetHeaderDownloadTask buildTaskForChangesets(Component parent, Collection<Changeset> changesets) {62 CheckParameterUtil.ensureParameterNotNull(parent, "parent");63 if (changesets == null) {64 changesets = Collections.emptyList();37 class DownloadTask extends RunnableDownloadTask { 38 /** the list of changeset ids to download */ 39 private final Set<Integer> toDownload = new HashSet<>(); 40 /** whether to include discussions or not */ 41 private final boolean includeDiscussion; 42 43 DownloadTask(Component parent, Collection<Integer> ids, boolean includeDiscussion) { 44 super(parent, tr("Download changesets")); 45 this.includeDiscussion = includeDiscussion; 46 for (int id: ids != null ? ids : Collections.<Integer>emptyList()) { 47 if (id <= 0) { 48 continue; 49 } 50 toDownload.add(id); 51 } 65 52 } 66 53 67 Set<Integer> ids = new HashSet<>(); 68 for (Changeset cs: changesets) { 69 if (cs == null || cs.isNew()) { 70 continue; 54 @Override 55 protected void realRun() throws SAXException, IOException, OsmTransferException { 56 try { 57 downloadedChangesets.addAll(reader.readChangesets(toDownload, includeDiscussion, 58 getProgressMonitor().createSubTaskMonitor(0, false))); 59 } catch (OsmTransferException e) { 60 if (isCanceled()) 61 // ignore exception if canceled 62 return; 63 // remember other exceptions 64 rememberLastException(e); 71 65 } 72 ids.add(cs.getId());73 66 } 74 if (parent == null)75 return new ChangesetHeaderDownloadTask(ids);76 else77 return new ChangesetHeaderDownloadTask(parent, ids);78 67 79 } 68 @Override 69 protected void finish() { 70 rememberDownloadedData(downloadedChangesets); 71 if (isCanceled()) 72 return; 73 if (lastException != null) { 74 ExceptionDialogUtil.explainException(lastException); 75 } 76 Runnable r = new Runnable() { 77 @Override 78 public void run() { 79 ChangesetCache.getInstance().update(downloadedChangesets); 80 } 81 }; 80 82 81 private Set<Integer> idsToDownload;82 private OsmServerChangesetReader reader;83 private boolean canceled;84 private Exception lastException;85 private Set<Changeset> downloadedChangesets;86 private final boolean includeDiscussion;87 88 protected void init(Collection<Integer> ids) {89 if (ids == null) {90 ids = Collections.emptyList();91 }92 idsToDownload = new HashSet<>();93 if (ids == null || ids.isEmpty())94 return;95 for (int id: ids) {96 if (id <= 0) {97 continue;83 if (SwingUtilities.isEventDispatchThread()) { 84 r.run(); 85 } else { 86 try { 87 SwingUtilities.invokeAndWait(r); 88 } catch (InterruptedException e) { 89 Main.warn("InterruptedException in "+getClass().getSimpleName()+" while updating changeset cache"); 90 } catch (InvocationTargetException e) { 91 Throwable t = e.getTargetException(); 92 if (t instanceof RuntimeException) { 93 BugReportExceptionHandler.handleException(t); 94 } else if (t instanceof Exception) { 95 ExceptionUtil.explainException(e); 96 } else { 97 BugReportExceptionHandler.handleException(t); 98 } 99 } 98 100 } 99 idsToDownload.add(id);100 101 } 101 102 } … … 110 111 */ 111 112 public ChangesetHeaderDownloadTask(Collection<Integer> ids) { 112 // parent for dialog is Main.parent 113 super(tr("Download changesets"), false /* don't ignore exceptions */); 114 init(ids); 115 this.includeDiscussion = false; 113 this(Main.parent, ids, false); 116 114 } 117 115 … … 143 141 */ 144 142 public ChangesetHeaderDownloadTask(Component dialogParent, Collection<Integer> ids, boolean includeDiscussion) { 145 super(dialogParent, tr("Download changesets"), false /* don't ignore exceptions */); 146 init(ids); 147 this.includeDiscussion = includeDiscussion; 143 downloadTask = new DownloadTask(dialogParent, ids, includeDiscussion); 144 setDownloadTask(downloadTask); 148 145 } 149 146 150 @Override 151 protected void cancel() { 152 canceled = true; 153 synchronized (this) { 154 if (reader != null) { 155 reader.cancel(); 156 } 157 } 147 /** 148 * Builds a download task from for a collection of changesets. 149 * 150 * Ignores null values and changesets with {@link Changeset#isNew()} == true. 151 * 152 * @param changesets the collection of changesets. Assumes an empty collection if null. 153 * @return the download task 154 */ 155 public static ChangesetHeaderDownloadTask buildTaskForChangesets(Collection<Changeset> changesets) { 156 return buildTaskForChangesets(Main.parent, changesets); 158 157 } 159 158 160 @Override 161 protected void finish() { 162 if (canceled) 163 return; 164 if (lastException != null) { 165 ExceptionDialogUtil.explainException(lastException); 159 /** 160 * Builds a download task from for a collection of changesets. 161 * 162 * Ignores null values and changesets with {@link Changeset#isNew()} == true. 163 * 164 * @param parent the parent component relative to which the {@link org.openstreetmap.josm.gui.PleaseWaitDialog} is displayed. 165 * Must not be null. 166 * @param changesets the collection of changesets. Assumes an empty collection if null. 167 * @return the download task 168 * @throws IllegalArgumentException if parent is null 169 */ 170 public static ChangesetHeaderDownloadTask buildTaskForChangesets(Component parent, Collection<Changeset> changesets) { 171 CheckParameterUtil.ensureParameterNotNull(parent, "parent"); 172 173 Set<Integer> ids = new HashSet<>(); 174 for (Changeset cs: changesets != null ? changesets : Collections.<Changeset>emptyList()) { 175 if (cs == null || cs.isNew()) { 176 continue; 177 } 178 ids.add(cs.getId()); 166 179 } 167 Runnable r = new Runnable() { 168 @Override 169 public void run() { 170 ChangesetCache.getInstance().update(downloadedChangesets); 171 } 172 }; 173 174 if (SwingUtilities.isEventDispatchThread()) { 175 r.run(); 176 } else { 177 try { 178 SwingUtilities.invokeAndWait(r); 179 } catch (InterruptedException e) { 180 Main.warn("InterruptedException in "+getClass().getSimpleName()+" while updating changeset cache"); 181 } catch (InvocationTargetException e) { 182 Throwable t = e.getTargetException(); 183 if (t instanceof RuntimeException) { 184 BugReportExceptionHandler.handleException(t); 185 } else if (t instanceof Exception) { 186 ExceptionUtil.explainException(e); 187 } else { 188 BugReportExceptionHandler.handleException(t); 189 } 190 } 191 } 192 } 193 194 @Override 195 protected void realRun() throws SAXException, IOException, OsmTransferException { 196 try { 197 synchronized (this) { 198 reader = new OsmServerChangesetReader(); 199 } 200 downloadedChangesets = new HashSet<>(); 201 downloadedChangesets.addAll(reader.readChangesets(idsToDownload, includeDiscussion, 202 getProgressMonitor().createSubTaskMonitor(0, false))); 203 } catch (OsmTransferException e) { 204 if (canceled) 205 // ignore exception if canceled 206 return; 207 // remember other exceptions 208 lastException = e; 209 } 210 } 211 212 /* ------------------------------------------------------------------------------- */ 213 /* interface ChangesetDownloadTask */ 214 /* ------------------------------------------------------------------------------- */ 215 @Override 216 public Set<Changeset> getDownloadedChangesets() { 217 return downloadedChangesets; 218 } 219 220 @Override 221 public boolean isCanceled() { 222 return canceled; 223 } 224 225 @Override 226 public boolean isFailed() { 227 return lastException != null; 180 if (parent == null) 181 return new ChangesetHeaderDownloadTask(ids); 182 else 183 return new ChangesetHeaderDownloadTask(parent, ids); 228 184 } 229 185 } -
trunk/src/org/openstreetmap/josm/actions/downloadtasks/ChangesetQueryTask.java
r10113 r10124 1 1 // License: GPL. For details, see LICENSE file. 2 package org.openstreetmap.josm. gui.dialogs.changeset.query;2 package org.openstreetmap.josm.actions.downloadtasks; 3 3 4 4 import static org.openstreetmap.josm.tools.I18n.tr; … … 7 7 import java.io.IOException; 8 8 import java.lang.reflect.InvocationTargetException; 9 import java.util.HashSet;10 import java.util.Set;11 9 12 10 import javax.swing.JOptionPane; … … 14 12 15 13 import org.openstreetmap.josm.Main; 16 import org.openstreetmap.josm.data.osm.Changeset;17 14 import org.openstreetmap.josm.data.osm.ChangesetCache; 18 15 import org.openstreetmap.josm.data.osm.UserInfo; 19 16 import org.openstreetmap.josm.gui.JosmUserIdentityManager; 20 import org.openstreetmap.josm.gui.PleaseWaitRunnable;21 import org.openstreetmap.josm.gui.dialogs.changeset.ChangesetDownloadTask;22 17 import org.openstreetmap.josm.gui.util.GuiHelper; 23 18 import org.openstreetmap.josm.io.ChangesetQuery; 24 import org.openstreetmap.josm.io.OsmServerChangesetReader;25 19 import org.openstreetmap.josm.io.OsmServerUserInfoReader; 26 20 import org.openstreetmap.josm.io.OsmTransferCanceledException; … … 35 29 * @since 2689 36 30 */ 37 public class ChangesetQueryTask extends PleaseWaitRunnable implementsChangesetDownloadTask {31 public class ChangesetQueryTask extends AbstractChangesetDownloadTask { 38 32 39 /** the changeset query */ 40 private ChangesetQuery query; 41 /** true if the task was canceled */ 42 private boolean canceled; 43 /** the set of downloaded changesets */ 44 private Set<Changeset> downloadedChangesets; 45 /** the last exception remembered, if any */ 46 private Exception lastException; 47 /** the reader object used to read information about the current user from the API */ 48 private OsmServerUserInfoReader userInfoReader; 49 /** the reader object used to submit the changeset query to the API */ 50 private OsmServerChangesetReader changesetReader; 33 private final DownloadTask downloadTask; 34 35 class DownloadTask extends RunnableDownloadTask { 36 /** the changeset query */ 37 private ChangesetQuery query; 38 /** the reader object used to read information about the current user from the API */ 39 private final OsmServerUserInfoReader userInfoReader = new OsmServerUserInfoReader(); 40 41 DownloadTask(Component parent, ChangesetQuery query) { 42 super(parent, tr("Querying and downloading changesets")); 43 this.query = query; 44 } 45 46 /** 47 * Tries to fully identify the current JOSM user 48 * 49 * @throws OsmTransferException if something went wrong 50 */ 51 protected void fullyIdentifyCurrentUser() throws OsmTransferException { 52 getProgressMonitor().indeterminateSubTask(tr("Determine user id for current user...")); 53 54 UserInfo info = userInfoReader.fetchUserInfo(getProgressMonitor().createSubTaskMonitor(1, false)); 55 JosmUserIdentityManager im = JosmUserIdentityManager.getInstance(); 56 im.setFullyIdentified(im.getUserName(), info); 57 } 58 59 @Override 60 protected void realRun() throws SAXException, IOException, OsmTransferException { 61 try { 62 JosmUserIdentityManager im = JosmUserIdentityManager.getInstance(); 63 if (query.isRestrictedToPartiallyIdentifiedUser() && im.isCurrentUser(query.getUserName())) { 64 // if we query changesets for the current user, make sure we query against 65 // its user id, not its user name. If necessary, determine the user id first. 66 // 67 if (im.isPartiallyIdentified()) { 68 fullyIdentifyCurrentUser(); 69 } 70 query = query.forUser(JosmUserIdentityManager.getInstance().getUserId()); 71 } 72 if (isCanceled()) 73 return; 74 getProgressMonitor().indeterminateSubTask(tr("Query and download changesets ...")); 75 downloadedChangesets.addAll(reader.queryChangesets(query, getProgressMonitor().createSubTaskMonitor(0, false))); 76 } catch (OsmTransferCanceledException e) { 77 // thrown if user cancel the authentication dialog 78 setCanceled(true); 79 } catch (OsmTransferException e) { 80 if (isCanceled()) 81 return; 82 rememberLastException(e); 83 } 84 } 85 86 @Override 87 protected void finish() { 88 rememberDownloadedData(downloadedChangesets); 89 if (isCanceled()) 90 return; 91 if (lastException != null) { 92 GuiHelper.runInEDTAndWait(new Runnable() { 93 private final Component parent = progressMonitor != null ? progressMonitor.getWindowParent() : null; 94 @Override 95 public void run() { 96 JOptionPane.showMessageDialog( 97 parent != null ? parent : Main.parent, 98 ExceptionUtil.explainException(lastException), 99 tr("Errors during download"), 100 JOptionPane.ERROR_MESSAGE); 101 } 102 }); 103 return; 104 } 105 106 // update the global changeset cache with the downloaded changesets. 107 // this will trigger change events which views are listening to. They 108 // will update their views accordingly. 109 // 110 // Run on the EDT because UI updates are triggered. 111 // 112 Runnable r = new Runnable() { 113 @Override public void run() { 114 ChangesetCache.getInstance().update(downloadedChangesets); 115 } 116 }; 117 if (SwingUtilities.isEventDispatchThread()) { 118 r.run(); 119 } else { 120 try { 121 SwingUtilities.invokeAndWait(r); 122 } catch (InterruptedException e) { 123 Main.warn("InterruptedException in "+getClass().getSimpleName()+" while updating changeset cache"); 124 } catch (InvocationTargetException e) { 125 Throwable t = e.getTargetException(); 126 if (t instanceof RuntimeException) { 127 BugReportExceptionHandler.handleException(t); 128 } else if (t instanceof Exception) { 129 ExceptionUtil.explainException(e); 130 } else { 131 BugReportExceptionHandler.handleException(t); 132 } 133 } 134 } 135 } 136 137 @Override 138 protected void cancel() { 139 super.cancel(); 140 synchronized (this) { 141 if (userInfoReader != null) { 142 userInfoReader.cancel(); 143 } 144 } 145 } 146 } 51 147 52 148 /** … … 57 153 */ 58 154 public ChangesetQueryTask(ChangesetQuery query) { 59 super(tr("Querying and downloading changesets"), false /* don't ignore exceptions */); 60 CheckParameterUtil.ensureParameterNotNull(query, "query"); 61 this.query = query; 155 this(Main.parent, query); 62 156 } 63 157 … … 72 166 */ 73 167 public ChangesetQueryTask(Component parent, ChangesetQuery query) { 74 super(parent, tr("Querying and downloading changesets"), false /* don't ignore exceptions */);75 168 CheckParameterUtil.ensureParameterNotNull(query, "query"); 76 this.query = query; 77 } 78 79 @Override 80 protected void cancel() { 81 canceled = true; 82 synchronized (this) { 83 if (userInfoReader != null) { 84 userInfoReader.cancel(); 85 } 86 } 87 synchronized (this) { 88 if (changesetReader != null) { 89 changesetReader.cancel(); 90 } 91 } 92 } 93 94 @Override 95 protected void finish() { 96 if (canceled) return; 97 if (lastException != null) { 98 GuiHelper.runInEDTAndWait(new Runnable() { 99 private final Component parent = progressMonitor != null ? progressMonitor.getWindowParent() : null; 100 @Override 101 public void run() { 102 JOptionPane.showMessageDialog( 103 parent != null ? parent : Main.parent, 104 ExceptionUtil.explainException(lastException), 105 tr("Errors during download"), 106 JOptionPane.ERROR_MESSAGE); 107 } 108 }); 109 return; 110 } 111 112 // update the global changeset cache with the downloaded changesets. 113 // this will trigger change events which views are listening to. They 114 // will update their views accordingly. 115 // 116 // Run on the EDT because UI updates are triggered. 117 // 118 Runnable r = new Runnable() { 119 @Override public void run() { 120 ChangesetCache.getInstance().update(downloadedChangesets); 121 } 122 }; 123 if (SwingUtilities.isEventDispatchThread()) { 124 r.run(); 125 } else { 126 try { 127 SwingUtilities.invokeAndWait(r); 128 } catch (InterruptedException e) { 129 Main.warn("InterruptedException in "+getClass().getSimpleName()+" while updating changeset cache"); 130 } catch (InvocationTargetException e) { 131 Throwable t = e.getTargetException(); 132 if (t instanceof RuntimeException) { 133 BugReportExceptionHandler.handleException(t); 134 } else if (t instanceof Exception) { 135 ExceptionUtil.explainException(e); 136 } else { 137 BugReportExceptionHandler.handleException(t); 138 } 139 } 140 } 141 } 142 143 /** 144 * Tries to fully identify the current JOSM user 145 * 146 * @throws OsmTransferException if something went wrong 147 */ 148 protected void fullyIdentifyCurrentUser() throws OsmTransferException { 149 getProgressMonitor().indeterminateSubTask(tr("Determine user id for current user...")); 150 151 synchronized (this) { 152 userInfoReader = new OsmServerUserInfoReader(); 153 } 154 UserInfo info = userInfoReader.fetchUserInfo(getProgressMonitor().createSubTaskMonitor(1, false)); 155 synchronized (this) { 156 userInfoReader = null; 157 } 158 JosmUserIdentityManager im = JosmUserIdentityManager.getInstance(); 159 im.setFullyIdentified(im.getUserName(), info); 160 } 161 162 @Override 163 protected void realRun() throws SAXException, IOException, OsmTransferException { 164 try { 165 JosmUserIdentityManager im = JosmUserIdentityManager.getInstance(); 166 if (query.isRestrictedToPartiallyIdentifiedUser() && im.isCurrentUser(query.getUserName())) { 167 // if we query changesets for the current user, make sure we query against 168 // its user id, not its user name. If necessary, determine the user id first. 169 // 170 if (im.isPartiallyIdentified()) { 171 fullyIdentifyCurrentUser(); 172 } 173 query = query.forUser(JosmUserIdentityManager.getInstance().getUserId()); 174 } 175 if (canceled) return; 176 getProgressMonitor().indeterminateSubTask(tr("Query and download changesets ...")); 177 synchronized (this) { 178 changesetReader = new OsmServerChangesetReader(); 179 } 180 downloadedChangesets = new HashSet<>(); 181 downloadedChangesets.addAll(changesetReader.queryChangesets(query, getProgressMonitor().createSubTaskMonitor(0, false))); 182 synchronized (this) { 183 changesetReader = null; 184 } 185 } catch (OsmTransferCanceledException e) { 186 // thrown if user cancel the authentication dialog 187 canceled = true; 188 } catch (OsmTransferException e) { 189 if (canceled) 190 return; 191 this.lastException = e; 192 } 193 } 194 195 /* ------------------------------------------------------------------------------- */ 196 /* interface ChangesetDownloadTask */ 197 /* ------------------------------------------------------------------------------- */ 198 @Override 199 public Set<Changeset> getDownloadedChangesets() { 200 return downloadedChangesets; 201 } 202 203 @Override 204 public boolean isCanceled() { 205 return canceled; 206 } 207 208 @Override 209 public boolean isFailed() { 210 return lastException != null; 169 downloadTask = new DownloadTask(parent, query); 170 setDownloadTask(downloadTask); 211 171 } 212 172 } -
trunk/src/org/openstreetmap/josm/gui/dialogs/ChangesetDialog.java
r10055 r10124 35 35 import org.openstreetmap.josm.Main; 36 36 import org.openstreetmap.josm.actions.AbstractInfoAction; 37 import org.openstreetmap.josm.actions.downloadtasks.ChangesetHeaderDownloadTask; 38 import org.openstreetmap.josm.actions.downloadtasks.PostDownloadHandler; 37 39 import org.openstreetmap.josm.data.osm.Changeset; 38 40 import org.openstreetmap.josm.data.osm.ChangesetCache; … … 44 46 import org.openstreetmap.josm.gui.SideButton; 45 47 import org.openstreetmap.josm.gui.dialogs.changeset.ChangesetCacheManager; 46 import org.openstreetmap.josm.gui.dialogs.changeset.ChangesetHeaderDownloadTask;47 48 import org.openstreetmap.josm.gui.dialogs.changeset.ChangesetInSelectionListModel; 48 49 import org.openstreetmap.josm.gui.dialogs.changeset.ChangesetListCellRenderer; … … 330 331 331 332 @Override 332 public void itemStateChanged(ItemEvent arg0) {333 public void itemStateChanged(ItemEvent e) { 333 334 updateEnabledState(); 334 335 … … 354 355 355 356 @Override 356 public void actionPerformed(ActionEvent arg0) {357 public void actionPerformed(ActionEvent e) { 357 358 ChangesetListModel model = getCurrentChangesetListModel(); 358 359 Set<Integer> sel = model.getSelectedChangesetIds(); … … 360 361 return; 361 362 ChangesetHeaderDownloadTask task = new ChangesetHeaderDownloadTask(sel); 362 Main.worker.submit( task);363 Main.worker.submit(new PostDownloadHandler(task, task.download())); 363 364 } 364 365 … … 368 369 369 370 @Override 370 public void itemStateChanged(ItemEvent arg0) { 371 updateEnabledState(); 372 371 public void itemStateChanged(ItemEvent e) { 372 updateEnabledState(); 373 373 } 374 374 … … 392 392 393 393 @Override 394 public void actionPerformed(ActionEvent arg0) {394 public void actionPerformed(ActionEvent e) { 395 395 List<Changeset> sel = getCurrentChangesetListModel().getSelectedOpenChangesets(); 396 396 if (sel.isEmpty()) … … 404 404 405 405 @Override 406 public void itemStateChanged(ItemEvent arg0) {406 public void itemStateChanged(ItemEvent e) { 407 407 updateEnabledState(); 408 408 } … … 427 427 428 428 @Override 429 public void actionPerformed(ActionEvent arg0) {429 public void actionPerformed(ActionEvent e) { 430 430 Set<Changeset> sel = getCurrentChangesetListModel().getSelectedChangesets(); 431 431 if (sel.isEmpty()) … … 435 435 String baseUrl = Main.getBaseBrowseUrl(); 436 436 for (Changeset cs: sel) { 437 String url = baseUrl + "/changeset/" + cs.getId(); 438 OpenBrowser.displayUrl( 439 url 440 ); 437 OpenBrowser.displayUrl(baseUrl + "/changeset/" + cs.getId()); 441 438 } 442 439 } … … 447 444 448 445 @Override 449 public void itemStateChanged(ItemEvent arg0) {446 public void itemStateChanged(ItemEvent e) { 450 447 updateEnabledState(); 451 448 } … … 469 466 470 467 @Override 471 public void actionPerformed(ActionEvent arg0) {468 public void actionPerformed(ActionEvent e) { 472 469 ChangesetListModel model = getCurrentChangesetListModel(); 473 470 Set<Integer> sel = model.getSelectedChangesetIds(); … … 521 518 } else { 522 519 task = new ChangesetHeaderDownloadTask(toDownload); 523 future = Main.worker.submit( task);520 future = Main.worker.submit(new PostDownloadHandler(task, task.download())); 524 521 } 525 522 -
trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetCacheManager.java
r9916 r10124 40 40 41 41 import org.openstreetmap.josm.Main; 42 import org.openstreetmap.josm.actions.downloadtasks.AbstractChangesetDownloadTask; 43 import org.openstreetmap.josm.actions.downloadtasks.ChangesetContentDownloadTask; 44 import org.openstreetmap.josm.actions.downloadtasks.ChangesetHeaderDownloadTask; 45 import org.openstreetmap.josm.actions.downloadtasks.ChangesetQueryTask; 46 import org.openstreetmap.josm.actions.downloadtasks.PostDownloadHandler; 42 47 import org.openstreetmap.josm.data.osm.Changeset; 43 48 import org.openstreetmap.josm.data.osm.ChangesetCache; … … 46 51 import org.openstreetmap.josm.gui.SideButton; 47 52 import org.openstreetmap.josm.gui.dialogs.changeset.query.ChangesetQueryDialog; 48 import org.openstreetmap.josm.gui.dialogs.changeset.query.ChangesetQueryTask;49 53 import org.openstreetmap.josm.gui.help.ContextSensitiveHelpAction; 50 54 import org.openstreetmap.josm.gui.help.HelpUtil; … … 652 656 public void setSelectedChangesets(Collection<Changeset> changesets) { 653 657 model.setSelectedChangesets(changesets); 654 int idx = model.getSelectionModel().getMinSelectionIndex(); 655 if (idx < 0) return; 656 tblChangesets.scrollRectToVisible(tblChangesets.getCellRect(idx, 0, true)); 658 final int idx = model.getSelectionModel().getMinSelectionIndex(); 659 if (idx < 0) 660 return; 661 GuiHelper.runInEDTAndWait(new Runnable() { 662 @Override 663 public void run() { 664 tblChangesets.scrollRectToVisible(tblChangesets.getCellRect(idx, 0, true)); 665 } 666 }); 657 667 repaint(); 658 668 } … … 696 706 * @param task The changeset download task to run 697 707 */ 698 public void runDownloadTask(final ChangesetDownloadTask task) {699 Main.worker.submit( task);708 public void runDownloadTask(final AbstractChangesetDownloadTask task) { 709 Main.worker.submit(new PostDownloadHandler(task, task.download())); 700 710 Main.worker.submit(new Runnable() { 701 711 @Override 702 712 public void run() { 703 if (task.isCanceled() || task.isFailed()) return; 704 setSelectedChangesets(task.getDownloadedChangesets()); 713 if (task.isCanceled() || task.isFailed()) 714 return; 715 setSelectedChangesets(task.getDownloadedData()); 705 716 } 706 717 }); -
trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetContentPanel.java
r10055 r10124 34 34 import org.openstreetmap.josm.Main; 35 35 import org.openstreetmap.josm.actions.AutoScaleAction; 36 import org.openstreetmap.josm.actions.downloadtasks.ChangesetContentDownloadTask; 36 37 import org.openstreetmap.josm.data.osm.Changeset; 37 38 import org.openstreetmap.josm.data.osm.OsmPrimitive; -
trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetDetailPanel.java
r9493 r10124 29 29 import org.openstreetmap.josm.Main; 30 30 import org.openstreetmap.josm.actions.AutoScaleAction; 31 import org.openstreetmap.josm.actions.downloadtasks.ChangesetHeaderDownloadTask; 32 import org.openstreetmap.josm.actions.downloadtasks.PostDownloadHandler; 31 33 import org.openstreetmap.josm.data.osm.Changeset; 32 34 import org.openstreetmap.josm.data.osm.ChangesetCache; … … 298 300 @Override 299 301 public void actionPerformed(ActionEvent evt) { 300 if (currentChangeset == null) return; 301 Main.worker.submit( 302 new ChangesetHeaderDownloadTask( 303 ChangesetDetailPanel.this, 304 Collections.singleton(currentChangeset.getId()) 305 ) 302 if (currentChangeset == null) 303 return; 304 ChangesetHeaderDownloadTask task = new ChangesetHeaderDownloadTask( 305 ChangesetDetailPanel.this, 306 Collections.singleton(currentChangeset.getId()) 306 307 ); 308 Main.worker.submit(new PostDownloadHandler(task, task.download())); 307 309 } 308 310 … … 313 315 314 316 /** 315 * Selects the primitives in the content of this changeset in the current 316 * data layer. 317 * Selects the primitives in the content of this changeset in the current data layer. 317 318 * 318 319 */ -
trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetDiscussionPanel.java
r8840 r10124 21 21 22 22 import org.openstreetmap.josm.Main; 23 import org.openstreetmap.josm.actions.downloadtasks.ChangesetHeaderDownloadTask; 24 import org.openstreetmap.josm.actions.downloadtasks.PostDownloadHandler; 23 25 import org.openstreetmap.josm.data.osm.Changeset; 24 26 import org.openstreetmap.josm.io.OnlineResource; … … 68 70 @Override 69 71 public void actionPerformed(ActionEvent evt) { 70 if (current == null) return; 71 Main.worker.submit( 72 new ChangesetHeaderDownloadTask( 73 ChangesetDiscussionPanel.this, 74 Collections.singleton(current.getId()), 75 true /* include discussion */ 76 ) 72 if (current == null) 73 return; 74 ChangesetHeaderDownloadTask task = new ChangesetHeaderDownloadTask( 75 ChangesetDiscussionPanel.this, 76 Collections.singleton(current.getId()), 77 true /* include discussion */ 77 78 ); 79 Main.worker.submit(new PostDownloadHandler(task, task.download())); 78 80 } 79 81 -
trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/DownloadChangesetContentAction.java
r9665 r10124 9 9 import javax.swing.AbstractAction; 10 10 11 import org.openstreetmap.josm.actions.downloadtasks.ChangesetContentDownloadTask; 11 12 import org.openstreetmap.josm.tools.CheckParameterUtil; 12 13 -
trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/SingleChangesetDownloadPanel.java
r9059 r10124 17 17 18 18 import org.openstreetmap.josm.Main; 19 import org.openstreetmap.josm.actions.downloadtasks.ChangesetContentDownloadTask; 19 20 import org.openstreetmap.josm.gui.SideButton; 20 21 import org.openstreetmap.josm.gui.widgets.ChangesetIdTextField;
Note:
See TracChangeset
for help on using the changeset viewer.