source: josm/trunk/src/org/openstreetmap/josm/actions/UploadAction.java@ 4067

Last change on this file since 4067 was 3671, checked in by bastiK, 13 years ago

adapt coding style (to some degree); there shouldn't be any semantic changes in this commit

  • Property svn:eol-style set to native
File size: 7.0 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.actions;
3
4import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
5import static org.openstreetmap.josm.tools.I18n.tr;
6
7import java.awt.event.ActionEvent;
8import java.awt.event.KeyEvent;
9import java.util.LinkedList;
10import java.util.logging.Logger;
11
12import javax.swing.JOptionPane;
13
14import org.openstreetmap.josm.Main;
15import org.openstreetmap.josm.actions.upload.ApiPreconditionCheckerHook;
16import org.openstreetmap.josm.actions.upload.RelationUploadOrderHook;
17import org.openstreetmap.josm.actions.upload.UploadHook;
18import org.openstreetmap.josm.actions.upload.ValidateUploadHook;
19import org.openstreetmap.josm.data.APIDataSet;
20import org.openstreetmap.josm.data.conflict.ConflictCollection;
21import org.openstreetmap.josm.gui.HelpAwareOptionPane;
22import org.openstreetmap.josm.gui.help.HelpUtil;
23import org.openstreetmap.josm.gui.io.UploadDialog;
24import org.openstreetmap.josm.gui.io.UploadPrimitivesTask;
25import org.openstreetmap.josm.gui.layer.OsmDataLayer;
26import org.openstreetmap.josm.tools.Shortcut;
27
28/**
29 * Action that opens a connection to the osm server and uploads all changes.
30 *
31 * An dialog is displayed asking the user to specify a rectangle to grab.
32 * The url and account settings from the preferences are used.
33 *
34 * If the upload fails this action offers various options to resolve conflicts.
35 *
36 * @author imi
37 */
38public class UploadAction extends JosmAction{
39 @SuppressWarnings("unused")
40 static private Logger logger = Logger.getLogger(UploadAction.class.getName());
41 /**
42 * The list of upload hooks. These hooks will be called one after the other
43 * when the user wants to upload data. Plugins can insert their own hooks here
44 * if they want to be able to veto an upload.
45 *
46 * Be default, the standard upload dialog is the only element in the list.
47 * Plugins should normally insert their code before that, so that the upload
48 * dialog is the last thing shown before upload really starts; on occasion
49 * however, a plugin might also want to insert something after that.
50 */
51 private static final LinkedList<UploadHook> uploadHooks = new LinkedList<UploadHook>();
52 static {
53 uploadHooks.add(new ValidateUploadHook());
54 /**
55 * Checks server capabilities before upload.
56 */
57 uploadHooks.add(new ApiPreconditionCheckerHook());
58
59 /**
60 * Adjusts the upload order of new relations
61 */
62 uploadHooks.add(new RelationUploadOrderHook());
63 }
64
65 /**
66 * Registers an upload hook. Adds the hook at the first position of the upload hooks.
67 *
68 * @param hook the upload hook. Ignored if null.
69 */
70 public static void registerUploadHook(UploadHook hook) {
71 if(hook == null) return;
72 if (!uploadHooks.contains(hook)) {
73 uploadHooks.add(0,hook);
74 }
75 }
76
77 /**
78 * Unregisters an upload hook. Removes the hook from the list of upload hooks.
79 *
80 * @param hook the upload hook. Ignored if null.
81 */
82 public static void unregisterUploadHook(UploadHook hook) {
83 if(hook == null) return;
84 if (uploadHooks.contains(hook)) {
85 uploadHooks.remove(hook);
86 }
87 }
88
89 public UploadAction() {
90 super(tr("Upload data"), "upload", tr("Upload all changes in the active data layer to the OSM server"),
91 Shortcut.registerShortcut("file:upload", tr("File: {0}", tr("Upload data")), KeyEvent.VK_U, Shortcut.GROUPS_ALT1+Shortcut.GROUP_HOTKEY), true);
92 putValue("help", ht("/Action/Upload"));
93 }
94
95 /**
96 * Refreshes the enabled state
97 *
98 */
99 @Override
100 protected void updateEnabledState() {
101 setEnabled(getEditLayer() != null);
102 }
103
104 public boolean checkPreUploadConditions(OsmDataLayer layer) {
105 return checkPreUploadConditions(layer, new APIDataSet(layer.data));
106 }
107
108 protected void alertUnresolvedConflicts(OsmDataLayer layer) {
109 HelpAwareOptionPane.showOptionDialog(
110 Main.parent,
111 tr("<html>The data to be uploaded participates in unresolved conflicts of layer ''{0}''.<br>"
112 + "You have to resolve them first.</html>", layer.getName()
113 ),
114 tr("Warning"),
115 JOptionPane.WARNING_MESSAGE,
116 HelpUtil.ht("/Action/Upload#PrimitivesParticipateInConflicts")
117 );
118 }
119
120 /**
121 * Check whether the preconditions are met to upload data in <code>apiData</code>.
122 * Makes sure primitives in <code>apiData</code> don't participate in conflicts and
123 * runs the installed {@see UploadHook}s.
124 *
125 * @param layer the source layer of the data to be uploaded
126 * @param apiData the data to be uploaded
127 * @return true, if the preconditions are met; false, otherwise
128 */
129 public boolean checkPreUploadConditions(OsmDataLayer layer, APIDataSet apiData) {
130 ConflictCollection conflicts = layer.getConflicts();
131 if (apiData.participatesInConflict(conflicts)) {
132 alertUnresolvedConflicts(layer);
133 return false;
134 }
135 // Call all upload hooks in sequence.
136 // FIXME: this should become an asynchronous task
137 //
138 for (UploadHook hook : uploadHooks) {
139 if (!hook.checkUpload(apiData))
140 return false;
141 }
142
143 return true;
144 }
145
146 /**
147 * Uploads data to the OSM API.
148 *
149 * @param layer the source layer for the data to upload
150 * @param apiData the primitives to be added, updated, or deleted
151 */
152 public void uploadData(OsmDataLayer layer, APIDataSet apiData) {
153 if (apiData.isEmpty()) {
154 JOptionPane.showMessageDialog(
155 Main.parent,
156 tr("No changes to upload."),
157 tr("Warning"),
158 JOptionPane.INFORMATION_MESSAGE
159 );
160 return;
161 }
162 if (!checkPreUploadConditions(layer, apiData))
163 return;
164
165 final UploadDialog dialog = UploadDialog.getUploadDialog();
166 dialog.setUploadedPrimitives(apiData);
167 dialog.setVisible(true);
168 if (dialog.isCanceled())
169 return;
170 dialog.rememberUserInput();
171
172 Main.worker.execute(
173 new UploadPrimitivesTask(
174 UploadDialog.getUploadDialog().getUploadStrategySpecification(),
175 layer,
176 apiData,
177 UploadDialog.getUploadDialog().getChangeset()
178 )
179 );
180 }
181
182 public void actionPerformed(ActionEvent e) {
183 if (!isEnabled())
184 return;
185 if (Main.map == null) {
186 JOptionPane.showMessageDialog(
187 Main.parent,
188 tr("Nothing to upload. Get some data first."),
189 tr("Warning"),
190 JOptionPane.WARNING_MESSAGE
191 );
192 return;
193 }
194 APIDataSet apiData = new APIDataSet(Main.main.getCurrentDataSet());
195 uploadData(Main.map.mapView.getEditLayer(), apiData);
196 }
197}
Note: See TracBrowser for help on using the repository browser.