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

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

add validator plugin to josm core. Original author: Francisco R. Santos (frsantos); major contributions by bilbo, daeron, delta_foxtrot, imi, jttt, jrreid, gabriel, guggis, pieren, rrankin, skela, stoecker, stotz and others

  • 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 return true;
143 }
144
145 /**
146 * Uploads data to the OSM API.
147 *
148 * @param layer the source layer for the data to upload
149 * @param apiData the primitives to be added, updated, or deleted
150 */
151 public void uploadData(OsmDataLayer layer, APIDataSet apiData) {
152 if (apiData.isEmpty()) {
153 JOptionPane.showMessageDialog(
154 Main.parent,
155 tr("No changes to upload."),
156 tr("Warning"),
157 JOptionPane.INFORMATION_MESSAGE
158 );
159 return;
160 }
161 if (!checkPreUploadConditions(layer, apiData))
162 return;
163
164 final UploadDialog dialog = UploadDialog.getUploadDialog();
165 dialog.setUploadedPrimitives(apiData);
166 dialog.setVisible(true);
167 if (dialog.isCanceled())
168 return;
169 dialog.rememberUserInput();
170
171 Main.worker.execute(
172 new UploadPrimitivesTask(
173 UploadDialog.getUploadDialog().getUploadStrategySpecification(),
174 layer,
175 apiData,
176 UploadDialog.getUploadDialog().getChangeset()
177 )
178 );
179 }
180
181 public void actionPerformed(ActionEvent e) {
182 if (!isEnabled())
183 return;
184 if (Main.map == null) {
185 JOptionPane.showMessageDialog(
186 Main.parent,
187 tr("Nothing to upload. Get some data first."),
188 tr("Warning"),
189 JOptionPane.WARNING_MESSAGE
190 );
191 return;
192 }
193 APIDataSet apiData = new APIDataSet(Main.main.getCurrentDataSet());
194 uploadData(Main.map.mapView.getEditLayer(), apiData);
195 }
196}
Note: See TracBrowser for help on using the repository browser.