Changeset 1523 in josm for trunk/src


Ignore:
Timestamp:
2009-04-06T20:18:48+02:00 (15 years ago)
Author:
framm
Message:
  • Major redesign of how JOSM talks to the OSM server. Connections now all go through a new OsmApi class that finds out which version the server uses. JOSM should now be able to handle 0.5 and 0.6 without configuration change. Config options osm-server.version and osm-server.additional-versions now obsolete. Handling of error and cancel situations might still need some improvement.
Location:
trunk/src/org/openstreetmap/josm
Files:
3 added
36 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/Main.java

    r1512 r1523  
    304304                    Main.pref.put("gui.geometry", geometry);
    305305                }
    306             } else
     306            } else {
    307307                System.out.println("Ignoring malformed geometry: "+geometry);
     308            }
    308309        }
    309310        if (bounds == null)
     
    432433    {
    433434        String full = Locale.getDefault().toString();
    434         if(full.equals("iw_IL"))
     435        if (full.equals("iw_IL"))
    435436            return "he";
    436437        /* list of non-single codes supported by josm */
    437         else if(full.equals("en_GB"))
     438        else if (full.equals("en_GB"))
    438439            return full;
    439440        return Locale.getDefault().getLanguage();
     
    444445        String newGeometry = "";
    445446        try {
    446             if(((JFrame)parent).getExtendedState() == JFrame.NORMAL) {
     447            if (((JFrame)parent).getExtendedState() == JFrame.NORMAL) {
    447448                Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
    448449                Rectangle bounds = parent.getBounds();
     
    451452                int x = (int)bounds.getX();
    452453                int y = (int)bounds.getY();
    453                 if(width > screenDimension.width)
     454                if (width > screenDimension.width)
    454455                    width = screenDimension.width;
    455                 if(height > screenDimension.height)
     456                if (height > screenDimension.height)
    456457                    width = screenDimension.height;
    457                 if(x < 0)
     458                if (x < 0)
    458459                    x = 0;
    459                 if(y < 0)
     460                if (y < 0)
    460461                    y = 0;
    461462                newGeometry = width + "x" + height + "+" + x + "+" + y;
  • trunk/src/org/openstreetmap/josm/actions/CopyAction.java

    r1514 r1523  
    88import java.awt.event.KeyEvent;
    99import java.util.ArrayList;
     10import java.util.Collection;
    1011import java.util.HashMap;
     12import java.util.LinkedList;
    1113import java.util.List;
    12 import java.util.LinkedList;
    13 import java.util.Collection;
    1414
    1515import javax.swing.JOptionPane;
     
    1919import org.openstreetmap.josm.data.osm.DataSet;
    2020import org.openstreetmap.josm.data.osm.DataSource;
     21import org.openstreetmap.josm.data.osm.Node;
     22import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2123import org.openstreetmap.josm.data.osm.Relation;
    2224import org.openstreetmap.josm.data.osm.RelationMember;
    23 import org.openstreetmap.josm.data.osm.Node;
    24 import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2525import org.openstreetmap.josm.data.osm.Way;
    26 import org.openstreetmap.josm.data.osm.visitor.Visitor;
     26import org.openstreetmap.josm.data.osm.visitor.AbstractVisitor;
    2727import org.openstreetmap.josm.tools.Shortcut;
    2828
     
    6565        /* scan the selected objects, mapping them to copies; when copying a way or relation,
    6666         * the copy references the copies of their child objects */
    67         new Visitor(){
     67        new AbstractVisitor() {
    6868            public void visit(Node n) {
    6969                /* check if already in pasteBuffer - e.g. two ways are selected which share a node;
  • trunk/src/org/openstreetmap/josm/actions/HistoryInfoAction.java

    r1433 r1523  
    1212
    1313import org.openstreetmap.josm.Main;
    14 import org.openstreetmap.josm.data.osm.Relation;
    1514import org.openstreetmap.josm.data.osm.Node;
    1615import org.openstreetmap.josm.data.osm.OsmPrimitive;
     16import org.openstreetmap.josm.data.osm.Relation;
    1717import org.openstreetmap.josm.data.osm.Way;
    18 import org.openstreetmap.josm.data.osm.visitor.Visitor;
     18import org.openstreetmap.josm.data.osm.visitor.AbstractVisitor;
    1919import org.openstreetmap.josm.tools.OpenBrowser;
    2020import org.openstreetmap.josm.tools.Shortcut;
     
    3131    public void actionPerformed(ActionEvent e) {
    3232        final Collection<Object> sel = new LinkedList<Object>();
    33         new Visitor() {
     33        new AbstractVisitor() {
    3434            public void visit(Node n) {
    3535                if(n.id <= 0) return;
  • trunk/src/org/openstreetmap/josm/actions/ReverseWayAction.java

    r1218 r1523  
    1919import org.openstreetmap.josm.corrector.UserCancelException;
    2020import org.openstreetmap.josm.data.osm.DataSet;
    21 import org.openstreetmap.josm.data.osm.Relation;
    2221import org.openstreetmap.josm.data.osm.Node;
    2322import org.openstreetmap.josm.data.osm.OsmPrimitive;
     23import org.openstreetmap.josm.data.osm.Relation;
    2424import org.openstreetmap.josm.data.osm.Way;
    25 import org.openstreetmap.josm.data.osm.visitor.Visitor;
     25import org.openstreetmap.josm.data.osm.visitor.AbstractVisitor;
    2626import org.openstreetmap.josm.tools.Shortcut;
    2727
     
    3535    public void actionPerformed(ActionEvent e) {
    3636        final Collection<Way> sel = new LinkedList<Way>();
    37         new Visitor() {
     37        new AbstractVisitor() {
    3838            public void visit(Node n) {
    3939            }
  • trunk/src/org/openstreetmap/josm/actions/SaveActionBase.java

    r1397 r1523  
    66import java.awt.event.ActionEvent;
    77import java.io.File;
    8 import java.io.FileOutputStream;
    98import java.io.FileInputStream;
    109import java.io.FileNotFoundException;
     10import java.io.FileOutputStream;
    1111import java.io.IOException;
     12import java.io.PrintWriter;
    1213
    1314import javax.swing.JFileChooser;
     
    1819import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1920import org.openstreetmap.josm.gui.ExtendedDialog;
     21import org.openstreetmap.josm.gui.layer.GpxLayer;
     22import org.openstreetmap.josm.gui.layer.Layer;
    2023import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    21 import org.openstreetmap.josm.gui.layer.Layer;
    22 import org.openstreetmap.josm.gui.layer.GpxLayer;
     24import org.openstreetmap.josm.io.GpxWriter;
    2325import org.openstreetmap.josm.io.OsmWriter;
    24 import org.openstreetmap.josm.io.GpxWriter;
    2526import org.openstreetmap.josm.tools.Shortcut;
    2627
     
    159160                    copy(file, tmpFile);
    160161                }
    161                 OsmWriter.output(new FileOutputStream(file), new OsmWriter.All(layer.data, false));
     162                OsmWriter w = new OsmWriter(new PrintWriter(new FileOutputStream(file)), false, layer.data.version);
     163                w.header();
     164                w.writeDataSources(layer.data);
     165                w.writeContent(layer.data);
     166                w.footer();
     167                // FIXME - how to close?
    162168                if (!Main.pref.getBoolean("save.keepbackup") && (tmpFile != null))
    163169                    tmpFile.delete();
  • trunk/src/org/openstreetmap/josm/actions/SplitWayAction.java

    r1499 r1523  
    3131import org.openstreetmap.josm.data.osm.RelationMember;
    3232import org.openstreetmap.josm.data.osm.Way;
     33import org.openstreetmap.josm.data.osm.visitor.AbstractVisitor;
    3334import org.openstreetmap.josm.data.osm.visitor.NameVisitor;
    3435import org.openstreetmap.josm.data.osm.visitor.Visitor;
     
    7475        selectedNodes = null;
    7576
    76         Visitor splitVisitor = new Visitor(){
     77        Visitor splitVisitor = new AbstractVisitor() {
    7778            public void visit(Node n) {
    7879                if (selectedNodes == null)
  • trunk/src/org/openstreetmap/josm/actions/UploadAction.java

    r1397 r1523  
    154154        PleaseWaitRunnable uploadTask = new PleaseWaitRunnable(tr("Uploading data")){
    155155            @Override protected void realRun() throws SAXException {
    156                 server.uploadOsm(all);
     156                server.uploadOsm(Main.ds.version, all);
    157157            }
    158158            @Override protected void finish() {
     
    160160            }
    161161            @Override protected void cancel() {
    162                 server.cancel();
     162                // FIXME server.cancel();
    163163            }
    164164        };
  • trunk/src/org/openstreetmap/josm/command/Command.java

    r1169 r1523  
    1212import org.openstreetmap.josm.Main;
    1313import org.openstreetmap.josm.data.osm.DataSet;
    14 import org.openstreetmap.josm.data.osm.Relation;
    1514import org.openstreetmap.josm.data.osm.Node;
    1615import org.openstreetmap.josm.data.osm.OsmPrimitive;
     16import org.openstreetmap.josm.data.osm.Relation;
    1717import org.openstreetmap.josm.data.osm.Way;
    18 import org.openstreetmap.josm.data.osm.visitor.Visitor;
     18import org.openstreetmap.josm.data.osm.visitor.AbstractVisitor;
    1919import org.openstreetmap.josm.gui.layer.Layer;
    2020import org.openstreetmap.josm.gui.layer.OsmDataLayer;
     
    3333abstract public class Command {
    3434
    35    private static final class CloneVisitor implements Visitor {
     35   private static final class CloneVisitor extends AbstractVisitor {
    3636      public Map<OsmPrimitive, OsmPrimitive> orig = new HashMap<OsmPrimitive, OsmPrimitive>();
    3737
  • trunk/src/org/openstreetmap/josm/data/osm/Changeset.java

    r1169 r1523  
    22package org.openstreetmap.josm.data.osm;
    33
    4 import org.openstreetmap.josm.Main;
    5 import org.openstreetmap.josm.io.XmlWriter;
    6 import org.openstreetmap.josm.io.XmlWriter.OsmWriterInterface;
    7 import java.io.PrintWriter;
    8 import java.util.Map;
    9 import java.util.Map.Entry;
    10 import java.util.HashMap;
    11 import java.util.Collections;
    12 import java.util.Collection;
     4import org.openstreetmap.josm.data.osm.visitor.Visitor;
     5
    136
    147
     
    1912 *
    2013 */
    21 public final class Changeset /*extends OsmPrimitive*/ implements OsmWriterInterface {
    22     /**
    23      * The key/value list for this primitive.
    24      */
    25     public Map<String, String> keys;
    26 
    27     public long id = 0;
    28 
    29     /**
    30      * User that created this changeset, as specified by the server.
    31      * Never changed by JOSM.
    32      */
    33     public User user = null;
    34 
     14public final class Changeset extends OsmPrimitive {
    3515    /**
    3616     * Time of last modification to this object. This is not set by JOSM but
     
    4525    public String start_timestamp = null;
    4626
    47         private void addTags(PrintWriter out) {
    48                 if (this.keys != null) {
    49                         for (Entry<String, String> e : this.keys.entrySet())
    50                                 out.println("    <tag k='"+ XmlWriter.encode(e.getKey()) +
    51                                                 "' v='"+XmlWriter.encode(e.getValue())+ "' />");
    52                 }
    53         }
    54 
    55     public final void header(PrintWriter out) {
    56             out.print("<osm version='");
    57                 out.print(Main.pref.get("osm-server.version", "0.6"));
    58                 out.println("' generator='JOSM'>");
    59     }
    60     public final void write(PrintWriter out) {
    61         out.print("  <changeset");
    62         if (id != 0)
    63             out.print(" id="+id);
    64         if (this.user != null) {
    65             out.print(" user='"+XmlWriter.encode(this.user.name)+"'");
    66         }
    67         out.println(">\n");
    68         addTags( out );
    69         out.println("  </changeset>");
    70     }
    71     public final void footer(PrintWriter out) {
    72         out.println("</osm>");
     27    public void visit(Visitor v) {
     28        v.visit(this);
    7329    }
    7430
    75     /******************************************************
    76      * This tag stuff is copied from OsmPrimitive. Perhaps a changeset
    77      * really is a primitive, but it's not right now. Perhaps it should
    78      * be...
    79      ******************************************************/
    80 
    81     /**
    82      * Set the given value to the given key
    83      * @param key The key, for which the value is to be set.
    84      * @param value The value for the key.
    85      */
    86     public final void put(String key, String value) {
    87         if (value == null)
    88             remove(key);
    89         else {
    90             if (keys == null)
    91                 keys = new HashMap<String, String>();
    92             keys.put(key, value);
    93         }
     31    public int compareTo(OsmPrimitive arg0) {
     32        if (arg0 instanceof Changeset) return Long.valueOf(id).compareTo(arg0.id);
     33        return 1;
    9434    }
    95     /**
    96      * Remove the given key from the list.
    97      */
    98     public final void remove(String key) {
    99         if (keys != null) {
    100             keys.remove(key);
    101             if (keys.isEmpty())
    102                 keys = null;
    103         }
    104     }
    105 
    106     public final String get(String key) {
    107         return keys == null ? null : keys.get(key);
    108     }
    109 
    110     public final Collection<Entry<String, String>> entrySet() {
    111         if (keys == null)
    112             return Collections.emptyList();
    113         return keys.entrySet();
    114     }
    115 
    116     public final Collection<String> keySet() {
    117         if (keys == null)
    118             return Collections.emptyList();
    119         return keys.keySet();
    120     }
     35   
     36   
    12137}
  • trunk/src/org/openstreetmap/josm/data/osm/DataSet.java

    r1415 r1523  
    2424public class DataSet implements Cloneable {
    2525
     26    /**
     27     * The API version that created this data set, if any.
     28     */
     29    public String version;
     30   
    2631    /**
    2732     * All nodes goes here, even when included in other data (ways etc). This enables the instant
     
    209214        for (DataSource source : dataSources)
    210215            ds.dataSources.add(new DataSource(source.bounds, source.origin));
     216        ds.version = version;
    211217        return ds;
    212218    }
  • trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java

    r1499 r1523  
    211211        final int[] ret = new int[1];
    212212        Visitor v = new Visitor(){
    213             public void visit(Node n) { ret[0] = 1; }
    214             public void visit(Way w) { ret[0] = 2; }
    215             public void visit(Relation e) { ret[0] = 3; }
     213            public void visit(Node n) { ret[0] = 0; }
     214            public void visit(Way w) { ret[0] = 1; }
     215            public void visit(Relation e) { ret[0] = 2; }
     216            public void visit(Changeset cs) { ret[0] = 3; }
    216217        };
    217218        visit(v);
  • trunk/src/org/openstreetmap/josm/data/osm/visitor/AddVisitor.java

    r1169 r1523  
    1414 * @author imi
    1515 */
    16 public class AddVisitor implements Visitor {
     16public class AddVisitor extends AbstractVisitor {
    1717
    1818    protected final DataSet ds;
  • trunk/src/org/openstreetmap/josm/data/osm/visitor/AllNodesVisitor.java

    r1169 r1523  
    1616 * @author imi
    1717 */
    18 public class AllNodesVisitor implements Visitor {
     18public class AllNodesVisitor extends AbstractVisitor {
    1919
    2020    /**
  • trunk/src/org/openstreetmap/josm/data/osm/visitor/BoundingXYVisitor.java

    r1415 r1523  
    1717 * @author imi
    1818 */
    19 public class BoundingXYVisitor implements Visitor {
     19public class BoundingXYVisitor extends AbstractVisitor {
    2020
    2121    public EastNorth min, max;
  • trunk/src/org/openstreetmap/josm/data/osm/visitor/CollectBackReferencesVisitor.java

    r1169 r1523  
    1919 * @author imi
    2020 */
    21 public class CollectBackReferencesVisitor implements Visitor {
     21public class CollectBackReferencesVisitor extends AbstractVisitor {
    2222
    2323    private final DataSet ds;
  • trunk/src/org/openstreetmap/josm/data/osm/visitor/CreateOsmChangeVisitor.java

    r1169 r1523  
    66import java.util.Map;
    77
    8 import org.openstreetmap.josm.Main;
    98import org.openstreetmap.josm.data.osm.Changeset;
    109import org.openstreetmap.josm.data.osm.Node;
     
    1211import org.openstreetmap.josm.data.osm.Relation;
    1312import org.openstreetmap.josm.data.osm.Way;
     13import org.openstreetmap.josm.io.OsmApi;
    1414import org.openstreetmap.josm.io.OsmWriter;
    1515
     
    2222 *
    2323 */
    24 public class CreateOsmChangeVisitor implements Visitor {
     24public class CreateOsmChangeVisitor extends AbstractVisitor {
    2525
    26     StringBuffer document;
    27     String currentMode;
    28     Changeset changeset;
    29     PrintWriter writer;
    30     StringWriter swriter;
    31     OsmWriter osmwriter;
     26    private String currentMode;
     27    private PrintWriter writer;
     28    private StringWriter swriter;
     29    private OsmWriter osmwriter;
     30    private OsmApi api;
    3231
    33     public CreateOsmChangeVisitor(Changeset changeset) {
     32    public CreateOsmChangeVisitor(Changeset changeset, OsmApi api) {
    3433        writer = new PrintWriter(swriter = new StringWriter());
    3534        writer.write("<osmChange version=\"");
    36         writer.write(Main.pref.get("osm-server.version", "0.6"));
     35        writer.write(api.getVersion());
    3736        writer.write("\" generator=\"JOSM\">\n");
    38         this.changeset = changeset;
    39         osmwriter = new OsmWriter(writer, false, changeset);
     37        this.api = api;
     38        // need to set osmConform = false here so that negative IDs get transmitted.
     39        // this also enables unnecessary and (if the API were more strict) potentially
     40        // harmful action="..." attributes.
     41        osmwriter = new OsmWriter(writer, false, api.getVersion());
     42        osmwriter.setChangeset(changeset);
    4043    }
    4144
     45    // FIXME: This should really NOT use a visitor pattern, it looks
     46    // stupid. Just have one method named "write" instead of three "visit"s.
     47   
    4248    public void visit(Node n) {
    4349        if (n.deleted) {
    4450            switchMode("delete");
    45             writer.write("<node id=\"");
    46             writer.write(Long.toString(n.id));
    47             writer.write("\" version=\"");
    48             writer.write(Long.toString(n.version));
    49             writer.write("\" changeset=\"");
    50             writer.write(Long.toString(changeset.id));
    51             writer.write("\" />\n");
     51            osmwriter.setWithBody(false);
     52            osmwriter.visit(n);
    5253        } else {
    5354            switchMode((n.id == 0) ? "create" : "modify");
    54             n.visit(osmwriter);
     55            osmwriter.setWithBody(true);
     56            osmwriter.visit(n);
    5557        }
    5658    }
    57 
    5859    public void visit(Way w) {
    5960        if (w.deleted) {
    6061            switchMode("delete");
    61             writer.write("<way id=\"");
    62             writer.write(Long.toString(w.id));
    63             writer.write("\" version=\"");
    64             writer.write(Long.toString(w.version));
    65             writer.write("\" changeset=\"");
    66             writer.write(Long.toString(changeset.id));
    67             writer.write("\" />\n");
     62            osmwriter.setWithBody(false);
     63            osmwriter.visit(w);
    6864        } else {
    6965            switchMode((w.id == 0) ? "create" : "modify");
    70             w.visit(osmwriter);
     66            osmwriter.setWithBody(true);
     67            osmwriter.visit(w);
    7168        }
    7269    }
    73 
    7470    public void visit(Relation r) {
    7571        if (r.deleted) {
    7672            switchMode("delete");
    77             writer.write("<relation id=\"");
    78             writer.write(Long.toString(r.id));
    79             writer.write("\" version=\"");
    80             writer.write(Long.toString(r.version));
    81             writer.write("\" changeset=\"");
    82             writer.write(Long.toString(changeset.id));
    83             writer.write("\" />\n");
     73            osmwriter.setWithBody(false);
     74            osmwriter.visit(r);
    8475        } else {
    8576            switchMode((r.id == 0) ? "create" : "modify");
    86             r.visit(osmwriter);
     77            osmwriter.setWithBody(true);
     78            osmwriter.visit(r);
    8779        }
    8880    }
    89 
     81   
    9082    private void switchMode(String newMode) {
    9183        if ((newMode != null && !newMode.equals(currentMode))||(newMode == null && currentMode != null)) {
     
    9991                writer.write(newMode);
    10092                writer.write(" version=\"");
    101                 writer.write(Main.pref.get("osm-server.version", "0.6"));
     93                writer.write(api.getVersion());
    10294                writer.write("\" generator=\"JOSM\">\n");
    10395            }
  • trunk/src/org/openstreetmap/josm/data/osm/visitor/DeleteVisitor.java

    r1169 r1523  
    1414 * @author imi
    1515 */
    16 public class DeleteVisitor implements Visitor {
     16public class DeleteVisitor extends AbstractVisitor {
    1717
    1818    private final DataSet ds;
  • trunk/src/org/openstreetmap/josm/data/osm/visitor/MapPaintVisitor.java

    r1501 r1523  
    1616import java.awt.Stroke;
    1717import java.awt.geom.GeneralPath;
     18import java.util.ArrayList;
    1819import java.util.Arrays;
    19 import java.util.ArrayList;
    2020import java.util.Collection;
     21import java.util.Iterator;
    2122import java.util.LinkedList;
    22 import java.util.Locale;
    23 import java.util.Iterator;
    2423
    2524import javax.swing.ImageIcon;
    2625
    2726import org.openstreetmap.josm.Main;
     27import org.openstreetmap.josm.data.coor.EastNorth;
     28import org.openstreetmap.josm.data.coor.LatLon;
    2829import org.openstreetmap.josm.data.osm.DataSet;
    2930import org.openstreetmap.josm.data.osm.Node;
     
    3233import org.openstreetmap.josm.data.osm.RelationMember;
    3334import org.openstreetmap.josm.data.osm.Way;
    34 import org.openstreetmap.josm.data.osm.visitor.SimplePaintVisitor;
    35 import org.openstreetmap.josm.data.coor.LatLon;
    36 import org.openstreetmap.josm.data.coor.EastNorth;
    3735import org.openstreetmap.josm.gui.mappaint.AreaElemStyle;
    3836import org.openstreetmap.josm.gui.mappaint.ElemStyle;
  • trunk/src/org/openstreetmap/josm/data/osm/visitor/MergeVisitor.java

    r1499 r1523  
    2222 * @author imi
    2323 */
    24 public class MergeVisitor implements Visitor {
     24public class MergeVisitor extends AbstractVisitor {
    2525
    2626    /**
  • trunk/src/org/openstreetmap/josm/data/osm/visitor/NameVisitor.java

    r1169 r1523  
    2020 * @author imi
    2121 */
    22 public class NameVisitor implements Visitor {
     22public class NameVisitor extends AbstractVisitor {
    2323
    2424    /**
  • trunk/src/org/openstreetmap/josm/data/osm/visitor/SimplePaintVisitor.java

    r1499 r1523  
    3333 * @author imi
    3434 */
    35 public class SimplePaintVisitor implements Visitor {
     35public class SimplePaintVisitor extends AbstractVisitor {
    3636
    3737    public final static Color darkerblue = new Color(0,0,96);
  • trunk/src/org/openstreetmap/josm/data/osm/visitor/Visitor.java

    r1169 r1523  
    22package org.openstreetmap.josm.data.osm.visitor;
    33
     4import org.openstreetmap.josm.data.osm.Changeset;
    45import org.openstreetmap.josm.data.osm.Relation;
    56import org.openstreetmap.josm.data.osm.Node;
     
    1617    void visit(Way w);
    1718    void visit(Relation e);
     19    void visit(Changeset cs);
    1820}
  • trunk/src/org/openstreetmap/josm/gui/MainApplication.java

    r1496 r1523  
    33package org.openstreetmap.josm.gui;
    44
    5 import org.xnap.commons.i18n.I18nFactory;
    65import static org.openstreetmap.josm.tools.I18n.i18n;
    76import static org.openstreetmap.josm.tools.I18n.tr;
     
    2625import org.openstreetmap.josm.tools.BugReportExceptionHandler;
    2726import org.openstreetmap.josm.tools.ImageProvider;
     27import org.xnap.commons.i18n.I18nFactory;
    2828
    2929/**
     
    9494        String localeName = null; // The locale to use
    9595
    96         //Check if passed as parameter
    97         if(args.containsKey("language"))
     96        // Check if passed as parameter
     97        if (args.containsKey("language"))
    9898            localeName = (String)(args.get("language").toArray()[0]);
    9999
     
    104104            Locale l;
    105105            Locale d = Locale.getDefault();
    106             if(localeName.equals("he")) localeName = "iw_IL";
     106            if (localeName.equals("he")) localeName = "iw_IL";
    107107            int i = localeName.indexOf('_');
    108108            if (i > 0) {
     
    115115                i18n = I18nFactory.getI18n(MainApplication.class);
    116116            } catch (MissingResourceException ex) {
    117                 if(!l.getLanguage().equals("en"))
    118                 {
     117                if (!l.getLanguage().equals("en")) {
    119118                    System.out.println(tr("Unable to find translation for the locale {0}. Reverting to {1}.",
    120119                    l.getDisplayName(), d.getDisplayName()));
    121120                    Locale.setDefault(d);
    122                 }
    123                 else
    124                 {
     121                } else {
    125122                    i18n = null;
    126123                }
     
    165162        splash.setStatus(tr("Setting defaults"));
    166163        preConstructorInit(args);
     164        removeObsoletePreferences();
    167165        splash.setStatus(tr("Creating main GUI"));
    168166        JFrame mainFrame = new JFrame(tr("Java OpenStreetMap Editor"));
     
    181179            mainFrame.setExtendedState(JFrame.MAXIMIZED_BOTH);
    182180
    183         EventQueue.invokeLater(new Runnable(){
     181        EventQueue.invokeLater(new Runnable() {
    184182            public void run() {
    185183                main.postConstructorProcessCmdLine(args);
     
    188186    }
    189187
    190 }
     188    /**
     189     * Removes obsolete preference settings. If you throw out a once-used preference
     190     * setting, add it to the list here with an expiry date (written as comment). If you
     191     * see something with an expiry date in the past, remove it from the list.
     192     */
     193    public static void removeObsoletePreferences() {
     194        String[] obsolete = {
     195           "sample.preference.that.does.not.exist", // sample comment, expiry date should go here
     196           "osm-server.version", // remove this around 10/2009
     197           "osm-server.additional-versions", // remove this around 10/2009
     198           null
     199        };
     200        for (String i : obsolete) {
     201            if (i == null) continue;
     202            if (Main.pref.hasKey(i)) {
     203                Main.pref.removeFromCollection(i, Main.pref.get(i));
     204                System.out.println(tr("Preference setting {0} has been removed since it is no longer used.", i));
     205            }
     206        }
     207    }     
     208 }
  • trunk/src/org/openstreetmap/josm/gui/dialogs/ConflictDialog.java

    r1419 r1523  
    22package org.openstreetmap.josm.gui.dialogs;
    33
     4import static org.openstreetmap.josm.tools.I18n.marktr;
    45import static org.openstreetmap.josm.tools.I18n.tr;
    5 import static org.openstreetmap.josm.tools.I18n.marktr;
    66
    77import java.awt.BorderLayout;
     
    2222import javax.swing.DefaultListModel;
    2323import javax.swing.JList;
    24 import javax.swing.JOptionPane;
    2524import javax.swing.JPanel;
    2625import javax.swing.JScrollPane;
     
    3332import org.openstreetmap.josm.data.SelectionChangedListener;
    3433import org.openstreetmap.josm.data.osm.DataSet;
     34import org.openstreetmap.josm.data.osm.Node;
     35import org.openstreetmap.josm.data.osm.OsmPrimitive;
    3536import org.openstreetmap.josm.data.osm.Relation;
    3637import org.openstreetmap.josm.data.osm.RelationMember;
    37 import org.openstreetmap.josm.data.osm.Node;
    38 import org.openstreetmap.josm.data.osm.OsmPrimitive;
    3938import org.openstreetmap.josm.data.osm.Way;
     39import org.openstreetmap.josm.data.osm.visitor.AbstractVisitor;
    4040import org.openstreetmap.josm.data.osm.visitor.Visitor;
    4141import org.openstreetmap.josm.gui.ConflictResolver;
     
    171171            return;
    172172        g.setColor(preferencesColor);
    173         Visitor conflictPainter = new Visitor(){
     173        Visitor conflictPainter = new AbstractVisitor(){
    174174            public void visit(Node n) {
    175175                Point p = nc.getPoint(n.eastNorth);
  • trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java

    r1508 r1523  
    2121import java.awt.image.BufferedImage;
    2222import java.io.File;
     23import java.util.ArrayList;
    2324import java.util.Collection;
    2425import java.util.HashSet;
     
    2627import java.util.LinkedList;
    2728import java.util.Set;
    28 import java.util.ArrayList;
    2929
    3030import javax.swing.AbstractAction;
     
    4343import org.openstreetmap.josm.data.coor.EastNorth;
    4444import org.openstreetmap.josm.data.coor.LatLon;
     45import org.openstreetmap.josm.data.gpx.GpxData;
     46import org.openstreetmap.josm.data.gpx.GpxTrack;
     47import org.openstreetmap.josm.data.gpx.WayPoint;
    4548import org.openstreetmap.josm.data.osm.DataSet;
    4649import org.openstreetmap.josm.data.osm.DataSource;
    47 import org.openstreetmap.josm.data.osm.Relation;
    4850import org.openstreetmap.josm.data.osm.Node;
    4951import org.openstreetmap.josm.data.osm.OsmPrimitive;
     52import org.openstreetmap.josm.data.osm.Relation;
    5053import org.openstreetmap.josm.data.osm.Way;
     54import org.openstreetmap.josm.data.osm.visitor.AbstractVisitor;
    5155import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
    5256import org.openstreetmap.josm.data.osm.visitor.MapPaintVisitor;
    5357import org.openstreetmap.josm.data.osm.visitor.MergeVisitor;
    5458import org.openstreetmap.josm.data.osm.visitor.SimplePaintVisitor;
    55 import org.openstreetmap.josm.data.osm.visitor.Visitor;
    56 import org.openstreetmap.josm.data.gpx.GpxData;
    57 import org.openstreetmap.josm.data.gpx.GpxTrack;
    58 import org.openstreetmap.josm.data.gpx.WayPoint;
    5959import org.openstreetmap.josm.gui.MapView;
    6060import org.openstreetmap.josm.gui.dialogs.ConflictDialog;
     
    7373public class OsmDataLayer extends Layer {
    7474
    75     public final static class DataCountVisitor implements Visitor {
     75    public final static class DataCountVisitor extends AbstractVisitor {
    7676        public final int[] normal = new int[3];
    7777        public final int[] deleted = new int[3];
     
    215215        tool += undeletedSize(data.nodes)+" "+trn("node", "nodes", undeletedSize(data.nodes))+", ";
    216216        tool += undeletedSize(data.ways)+" "+trn("way", "ways", undeletedSize(data.ways));
     217        if (data.version != null) tool += ", " + tr("version {0}", data.version);
    217218        if (associatedFile != null)
    218219            tool = "<html>"+tool+"<br>"+associatedFile.getPath()+"</html>";
     
    236237        for (DataSource src : ((OsmDataLayer)from).data.dataSources)
    237238            data.dataSources.add(src);
     239       
     240        // copy the merged layer's API version, downgrade if required
     241        if (data.version == null) {
     242            data.version = ((OsmDataLayer)from).data.version;
     243        } else {
     244            if ("0.5".equals(data.version) ^ "0.5".equals(((OsmDataLayer)from).data.version)) {
     245                System.err.println("Warning: mixing 0.6 and 0.5 data results in version 0.5");
     246                data.version = "0.5";
     247            }
     248        }
    238249        fireDataChange();
    239250        // repaint to make sure new data is displayed properly.
     
    349360            p.add(new JLabel(s, ImageProvider.get("data", counter.names[i]), JLabel.HORIZONTAL), GBC.eop().insets(15,0,0,0));
    350361        }
     362        p.add(new JLabel(tr("API version: {0}", (data.version != null) ? data.version : tr("unset"))));
     363
    351364        return p;
    352365    }
     
    447460    }
    448461
    449     public boolean containsPoint(LatLon coor)
    450     {
     462    public boolean containsPoint(LatLon coor) {
    451463        // we'll assume that if this has no data sources
    452464        // that it also has no borders
  • trunk/src/org/openstreetmap/josm/io/DiffResultReader.java

    r1415 r1523  
    55
    66import java.io.IOException;
    7 import java.io.InputStream;
    8 import java.io.InputStreamReader;
     7import java.io.StringReader;
    98import java.util.Collection;
    109import java.util.HashMap;
     
    1817import org.openstreetmap.josm.data.osm.Relation;
    1918import org.openstreetmap.josm.data.osm.Way;
    20 import org.openstreetmap.josm.data.osm.visitor.Visitor;
     19import org.openstreetmap.josm.data.osm.visitor.AbstractVisitor;
    2120import org.openstreetmap.josm.gui.PleaseWaitDialog;
    2221import org.xml.sax.Attributes;
     
    2726/**
    2827 */
    29 public class DiffResultReader implements Visitor {
     28public class DiffResultReader extends AbstractVisitor {
    3029
    3130    /**
     
    6564     * Parse the given input source and return the dataset.
    6665     */
    67     public static void parseDiffResult(InputStream source, Collection<OsmPrimitive> osm, Collection<OsmPrimitive> processed, Map<OsmPrimitive,Long> newIdMap, PleaseWaitDialog pleaseWaitDlg)
     66    public static void parseDiffResult(String source, Collection<OsmPrimitive> osm, Collection<OsmPrimitive> processed, Map<OsmPrimitive,Long> newIdMap, PleaseWaitDialog pleaseWaitDlg)
    6867    throws SAXException, IOException {
    6968
     
    7170       drr.processed = processed;
    7271       drr.newIdMap = newIdMap;
    73        InputSource inputSource = new InputSource(new InputStreamReader(source, "UTF-8"));
     72       InputSource inputSource = new InputSource(new StringReader(source));
    7473       try {
    7574           SAXParserFactory.newInstance().newSAXParser().parse(inputSource, drr.new Parser());
     
    8584
    8685       for (OsmPrimitive p : osm) {
    87            System.out.println("old: "+ p);
     86           //System.out.println("old: "+ p);
    8887           p.visit(drr);
    89            System.out.println("new: "+ p);
    90            System.out.println("");
     88           //System.out.println("new: "+ p);
     89           //System.out.println("");
    9190       }
    9291    }
  • trunk/src/org/openstreetmap/josm/io/MirroredInputStream.java

    r1169 r1523  
    2222    InputStream fs = null;
    2323
    24     public MirroredInputStream(String name) throws IOException
    25     {
     24    public MirroredInputStream(String name) throws IOException {
    2625        this(name, null, -1L);
    2726    }
    2827
    29     public MirroredInputStream(String name, long maxTime) throws IOException
    30     {
     28    public MirroredInputStream(String name, long maxTime) throws IOException {
    3129        this(name, null, maxTime);
    3230    }
    3331
    34     public MirroredInputStream(String name, String destDir, long maxTime) throws IOException
    35     {
     32    public MirroredInputStream(String name, String destDir, long maxTime) throws IOException {
    3633        URL url;
    3734        File file = null;
    38         try
    39         {
     35        try {
    4036            url = new URL(name);
    41             if(url.getProtocol().equals("file"))
    42             {
     37            if (url.getProtocol().equals("file")) {
    4338                file = new File(name.substring("file:/".length()));
    44                 if(!file.exists())
     39                if (!file.exists())
    4540                    file = new File(name.substring("file://".length()));
     41            } else {
     42                file = checkLocal(url, destDir, maxTime);
    4643            }
    47             else
    48                 file = checkLocal(url, destDir, maxTime);
    49         }
    50         catch(java.net.MalformedURLException e)
    51         {
    52             if(name.startsWith("resource://"))
    53             {
     44        } catch (java.net.MalformedURLException e) {
     45            if(name.startsWith("resource://")) {
    5446                fs = getClass().getResourceAsStream(
    5547                name.substring("resource:/".length()));
    5648                return;
    5749            }
    58             else
    59                 file = new File(name);
     50            file = new File(name);
    6051        }
    61         if(file == null)
     52        if (file == null)
    6253            throw new IOException();
    6354        fs = new FileInputStream(file);
    6455    }
    6556
    66     private File checkLocal(URL url, String destDir, long maxTime)
    67     {
     57    private File checkLocal(URL url, String destDir, long maxTime) {
    6858        String localPath = Main.pref.get("mirror." + url);
    6959        File file = null;
    70         if(localPath != null && localPath.length() > 0)
    71         {
     60        if (localPath != null && localPath.length() > 0) {
    7261            String[] lp = localPath.split(";");
    7362            file = new File(lp[1]);
    74             if(maxTime <= 0)
     63            if (maxTime <= 0)
    7564                maxTime = Main.pref.getInteger("mirror.maxtime", 7*24*60*60);
    76             if(System.currentTimeMillis() - Long.parseLong(lp[0]) < maxTime*1000)
    77             {
    78                 if(file.exists())
    79                 {
     65            if (System.currentTimeMillis() - Long.parseLong(lp[0]) < maxTime*1000) {
     66                if(file.exists()) {
    8067                    return file;
    8168                }
     
    8673
    8774        File destDirFile = new File(destDir);
    88         if(!destDirFile.exists() )
     75        if (!destDirFile.exists())
    8976            destDirFile.mkdirs();
    9077
     
    9380        BufferedOutputStream bos = null;
    9481        BufferedInputStream bis = null;
    95         try
    96         {
     82        try {
    9783            URLConnection conn = url.openConnection();
    9884            conn.setConnectTimeout(5000);
     
    10187            byte[] buffer = new byte[4096];
    10288            int length;
    103             while((length = bis.read(buffer)) > -1)
     89            while ((length = bis.read(buffer)) > -1)
    10490                bos.write(buffer, 0, length);
    105         }
    106         catch(IOException ioe)
    107         {
    108             if(file != null)
     91        } catch(IOException ioe) {
     92            if (file != null)
    10993                return file;
    110             else
    111                 return null;
    112         }
    113         finally
    114         {
    115             if(bis != null)
    116             {
    117                 try
    118                 {
     94            return null;
     95        } finally {
     96            if (bis != null) {
     97                try {
    11998                    bis.close();
    120                 }
    121                 catch (IOException e)
    122                 {
     99                } catch (IOException e) {
    123100                    e.printStackTrace();
    124101                }
    125102            }
    126             if(bos != null)
    127             {
    128                 try
    129                 {
     103            if (bos != null) {
     104                try {
    130105                    bos.close();
    131                 }
    132                 catch (IOException e)
    133                 {
     106                } catch (IOException e) {
    134107                    e.printStackTrace();
    135108                }
  • trunk/src/org/openstreetmap/josm/io/MyHttpHandler.java

    r1169 r1523  
    99// Basically a copy of sun.net.www.protocol.http.Handler
    1010public class MyHttpHandler extends sun.net.www.protocol.http.Handler  {
    11             protected String proxy;
    12             protected int proxyPort;
     11    protected String proxy;
     12    protected int proxyPort;
    1313
    14             public MyHttpHandler() {
    15                 super();
    16                 proxy = null;
    17                 proxyPort = -1;
    18             }
     14    public MyHttpHandler() {
     15        super();
     16        proxy = null;
     17        proxyPort = -1;
     18    }
    1919
    20             protected java.net.URLConnection openConnection(URL u)
    21                     throws IOException {
    22                 return openConnection(u, (Proxy) null);
    23             }
    24             public MyHttpHandler(String proxy, int port) {
    25                 this.proxy = proxy;
    26                 proxyPort = port;
    27             }
     20    protected java.net.URLConnection openConnection(URL u)
     21    throws IOException {
     22        return openConnection(u, (Proxy) null);
     23    }
     24    public MyHttpHandler(String proxy, int port) {
     25        this.proxy = proxy;
     26        proxyPort = port;
     27    }
    2828
    29             protected java.net.URLConnection openConnection(URL u, Proxy p)
    30                     throws IOException {
    31                 return new MyHttpURLConnection(u, p, this);
    32             }
     29    protected java.net.URLConnection openConnection(URL u, Proxy p)
     30    throws IOException {
     31        return new MyHttpURLConnection(u, p, this);
     32    }
    3333}
  • trunk/src/org/openstreetmap/josm/io/OsmConnection.java

    r1397 r1523  
    4949     */
    5050    static {
    51         //TODO: refactor this crap (maybe just insert the damn auth http-header by yourself)
     51        // TODO: current authentication handling is sub-optimal in that it seems to use the same authenticator for
     52        // any kind of request. HTTP requests executed by plugins, e.g. to password-protected WMS servers,
     53        // will use the same username/password which is undesirable.
    5254        try {
    5355            HttpURLConnection.setFollowRedirects(true);
  • trunk/src/org/openstreetmap/josm/io/OsmReader.java

    r1499 r1523  
    88import java.io.InputStreamReader;
    99import java.util.ArrayList;
    10 import java.util.Arrays;
    1110import java.util.Collection;
    1211import java.util.HashMap;
    13 import java.util.HashSet;
    1412import java.util.LinkedList;
    1513import java.util.Map;
     
    130128     private Map<OsmPrimitiveData, Collection<RelationMemberData>> relations = new HashMap<OsmPrimitiveData, Collection<RelationMemberData>>();
    131129
    132      /**
    133       * List of protocol versions that will be accepted on reading
    134       */
    135      private HashSet<String> allowedVersions = new HashSet<String>();
    136 
    137130     private class Parser extends DefaultHandler {
    138131          /**
     
    164157                         if (atts == null)
    165158                              throw new SAXException(tr("Unknown version"));
    166                          if (!allowedVersions.contains(atts.getValue("version")))
    167                               throw new SAXException(tr("Unknown version")+": "+atts.getValue("version"));
     159                         String v = atts.getValue("version");
     160                         if (v == null)
     161                             throw new SAXException(tr("Version number missing from OSM data"));
     162                         if (!(v.equals("0.5") || v.equals("0.6")))
     163                             throw new SAXException(tr("Unknown version: {0}", v));
    168164                         // save generator attribute for later use when creating DataSource objects
    169165                         generator = atts.getValue("generator");
    170 
    171 
    172                     } else if (qName.equals("bound")) {
    173                          // old style bounds.
    174                          // TODO: remove this around 1st October 2008.
    175                          // - this is a bit of a hack; since we still write out old style bound objects,
    176                          // we don't want to load them both. so when writing, we add a "note" tag the our
    177                          // old-style bound, and when reading, ignore those with a "note".
    178                          String note = atts.getValue("note");
    179                          if (note == null) {
    180                              System.out.println("Notice: old style <bound> element detected; support for these will be dropped in a future release.");
    181                              String bbox = atts.getValue("box");
    182                              String origin = atts.getValue("origin");
    183                              if (origin == null) origin = "";
    184                              if (bbox != null) {
    185                                   String[] b = bbox.split(",");
    186                                   Bounds bounds = new Bounds();
    187                                   if (b.length == 4)
    188                                        bounds = new Bounds(
    189                                                  new LatLon(Double.parseDouble(b[0]),Double.parseDouble(b[1])),
    190                                                  new LatLon(Double.parseDouble(b[2]),Double.parseDouble(b[3])));
    191                                   DataSource src = new DataSource(bounds, origin);
    192                                   ds.dataSources.add(src);
    193                              }
    194                          }
     166                         ds.version = v;
     167                         
    195168                    } else if (qName.equals("bounds")) {
    196169                         // new style bounds.
     
    277250               return Double.parseDouble(atts.getValue(value));
    278251          }
    279      }
    280 
    281      /**
    282       * Constructor initializes list of allowed protocol versions.
    283       */
    284      public OsmReader() {
    285           // first add the main server version
    286           allowedVersions.add(Main.pref.get("osm-server.version", "0.5"));
    287           // now also add all compatible versions
    288           String[] additionalVersions =
    289                Main.pref.get("osm-server.additional-versions", "").split("/,/");
    290           if (additionalVersions.length == 1 && additionalVersions[0].length() == 0)
    291                additionalVersions = new String[] {};
    292           allowedVersions.addAll(Arrays.asList(additionalVersions));
    293252     }
    294253
     
    491450          osm.references = ref == null ? new DataSet() : ref;
    492451
    493 
    494452          currSource = source;
    495453
  • trunk/src/org/openstreetmap/josm/io/OsmServerLocationReader.java

    r1169 r1523  
    3232            Main.pleaseWaitDlg.currentAction.setText(tr("Downloading OSM data..."));
    3333            final DataSet data = OsmReader.parseDataSet(in, null, Main.pleaseWaitDlg);
    34 //          String origin = Main.pref.get("osm-server.url")+"/"+Main.pref.get("osm-server.version", "0.5");
    3534//          Bounds bounds = new Bounds(new LatLon(lat1, lon1), new LatLon(lat2, lon2));
    3635//          DataSource src = new DataSource(bounds, origin);
  • trunk/src/org/openstreetmap/josm/io/OsmServerObjectReader.java

    r1444 r1523  
    5252            final DataSet data = osm.getDs();
    5353
    54 //          String origin = Main.pref.get("osm-server.url")+"/"+Main.pref.get("osm-server.version", "0.5");
    5554//          Bounds bounds = new Bounds(new LatLon(lat1, lon1), new LatLon(lat2, lon2));
    5655//          DataSource src = new DataSource(bounds, origin);
  • trunk/src/org/openstreetmap/josm/io/OsmServerReader.java

    r1353 r1523  
    2727 */
    2828public abstract class OsmServerReader extends OsmConnection {
     29   
     30    private OsmApi api = new OsmApi();
     31   
    2932    /**
    3033     * Open a connection to the given url and return a reader on the input stream
     
    3538     */
    3639    protected InputStream getInputStream(String urlStr, PleaseWaitDialog pleaseWaitDlg) throws IOException {
    37         String version = Main.pref.get("osm-server.version", "0.5");
    38         urlStr = Main.pref.get("osm-server.url")+"/"+version+"/" + urlStr;
     40        api.initialize();
     41        urlStr = api.getBaseUrl() + urlStr;
    3942        return getInputStreamRaw(urlStr, pleaseWaitDlg);
    4043    }
     
    4346
    4447//        System.out.println("download: "+urlStr);
    45         initAuthentication();
    4648        URL url = new URL(urlStr);
    4749        activeConnection = (HttpURLConnection)url.openConnection();
  • trunk/src/org/openstreetmap/josm/io/OsmServerWriter.java

    r1415 r1523  
    44import static org.openstreetmap.josm.tools.I18n.tr;
    55
    6 import java.io.BufferedReader;
    7 import java.io.ByteArrayOutputStream;
    8 import java.io.IOException;
    9 import java.io.InputStream;
    10 import java.io.InputStreamReader;
    11 import java.io.OutputStream;
    12 import java.io.OutputStreamWriter;
    13 import java.io.PrintWriter;
    14 import java.io.UnsupportedEncodingException;
    15 import java.lang.Math;
    16 import java.net.ConnectException;
    17 import java.net.HttpURLConnection;
    18 import java.net.URL;
    19 import java.net.UnknownHostException;
    20 import java.net.SocketTimeoutException;
    216import java.util.Collection;
    227import java.util.LinkedList;
     8
    239import javax.swing.JOptionPane;
    2410
    2511import org.openstreetmap.josm.Main;
    26 import org.openstreetmap.josm.data.osm.Relation;
    27 import org.openstreetmap.josm.data.osm.Node;
    2812import org.openstreetmap.josm.data.osm.OsmPrimitive;
    29 import org.openstreetmap.josm.data.osm.Way;
    30 import org.openstreetmap.josm.data.osm.Changeset;
    31 import org.openstreetmap.josm.data.osm.visitor.CreateOsmChangeVisitor;
    3213import org.openstreetmap.josm.data.osm.visitor.NameVisitor;
    33 import org.openstreetmap.josm.data.osm.visitor.Visitor;
    34 import org.xml.sax.SAXException;
    35 import org.openstreetmap.josm.io.XmlWriter.OsmWriterInterface;
    3614
    3715/**
     
    4119 * those in deleted, which are ignored - All objects in deleted list are
    4220 * deleted. - All remaining objects with modified flag set are updated.
    43  *
    44  * This class implements visitor and will perform the correct upload action on
    45  * the visited element.
    46  *
    47  * @author imi
    4821 */
    49 public class OsmServerWriter extends OsmConnection implements Visitor {
     22public class OsmServerWriter {
    5023
    5124    /**
     
    5831    public Collection<OsmPrimitive> processed;
    5932
    60     /**
    61      * Whether the operation should be aborted as soon as possible.
    62      */
    63     // use the inherited variable
    64     // private boolean cancel = false;
    65 
    66     /**
    67      * Object describing current changeset
    68      */
    69     private Changeset changeset;
    70 
    71     /**
    72      * Send the dataset to the server. Ask the user first and does nothing if he
    73      * does not want to send the data.
    74      */
     33    private OsmApi api = new OsmApi();
     34   
    7535    private static final int MSECS_PER_SECOND = 1000;
    7636    private static final int SECONDS_PER_MINUTE = 60;
     
    9656    }
    9757
    98     public void uploadOsm(Collection<OsmPrimitive> list) throws SAXException {
     58    /**
     59     * Send the dataset to the server.
     60     * @param the_version version of the data set
     61     * @param list list of objects to send
     62     */
     63    public void uploadOsm(String the_version, Collection<OsmPrimitive> list) {
    9964        processed = new LinkedList<OsmPrimitive>();
    100         initAuthentication();
     65        api.initialize();
    10166
    10267        Main.pleaseWaitDlg.progress.setMaximum(list.size());
    10368        Main.pleaseWaitDlg.progress.setValue(0);
    10469
    105         // controls whether or not we open and close a changeset. API 0.6 requires changesets.
    106         boolean useChangesets = Main.pref.get("osm-server.version", "0.5").equals("0.6");
     70        boolean useChangesets = api.hasChangesetSupport();
     71       
     72        // controls whether or not we try and upload the whole bunch in one go
     73        boolean useDiffUploads = Main.pref.getBoolean("osm-server.atomic-upload",
     74            "0.6".equals(api.getVersion()));
    10775
    108         // controls whether or not we try and uplaod the whole bunch in one go
    109         boolean useDiffUploads = Main.pref.getBoolean("osm-server.atomic-upload",
    110             Main.pref.get("osm-server.version", "0.5").equals("0.6"));
    111 
     76        // solicit commit comment from user
    11277        String comment = null;
    11378        while (useChangesets && comment == null) {
     
    11782            if (comment == null)
    11883                return;
    119             /* Don't let people just hit enter */
    120             if( comment.trim().length() >= 3 )
     84            // Don't let people just hit enter
     85            if (comment.trim().length() >= 3)
    12186                break;
    12287            comment = null;
    12388        }
     89       
     90        // create changeset if required
    12491        try {
    125             if (useChangesets && !startChangeset(10, comment))
    126                 return;
    127         }
    128         catch (OsmTransferException ex) {
     92            if (useChangesets) api.createChangeset(comment);
     93        } catch (OsmTransferException ex) {
    12994            dealWithTransferException(ex);
    13095            return;
     
    13398        try {
    13499            if (useDiffUploads) {
    135                 uploadDiff(10, list);
     100                // all in one go
     101                processed.addAll(api.uploadDiff(list));
    136102            } else {
     103                // upload changes individually (90% of code is for the status display...)
    137104                NameVisitor v = new NameVisitor();
    138105                uploadStartTime = System.currentTimeMillis();
    139106                for (OsmPrimitive osm : list) {
    140                     if (cancel)
    141                         return;
    142107                    osm.visit(v);
    143108                    int progress = Main.pleaseWaitDlg.progress.getValue();
    144109                    String time_left_str = timeLeft(progress, list.size());
    145110                    Main.pleaseWaitDlg.currentAction.setText(
    146                     tr("{0}% ({1}/{2}), {3} left. Uploading {4}: {5} (id: {6})",
    147                     Math.round(100.0*progress/list.size()), progress,
    148                     list.size(), time_left_str, tr(v.className), v.name, osm.id));
    149                     osm.visit(this);
     111                            tr("{0}% ({1}/{2}), {3} left. Uploading {4}: {5} (id: {6})",
     112                                    Math.round(100.0*progress/list.size()), progress,
     113                                    list.size(), time_left_str, tr(v.className), v.name, osm.id));
     114                    makeApiRequest(osm);
     115                    processed.add(osm);
    150116                    Main.pleaseWaitDlg.progress.setValue(progress+1);
    151117                }
    152118            }
    153             if (useChangesets) stopChangeset(10);
    154         } catch (RuntimeException e) {
     119            if (useChangesets) api.stopChangeset();
     120        } catch (OsmTransferException e) {
    155121            try {
    156                 if (useChangesets) stopChangeset(10);
    157             }
    158             catch (OsmTransferException ex) {
    159                 dealWithTransferException(ex);
    160             }
    161             e.printStackTrace();
    162             throw new SAXException(tr("An error occurred: {0}",e.getMessage()));
    163         }
    164         catch (OsmTransferException e) {
    165             try {
    166                 if (useChangesets) stopChangeset(10);
    167             }
    168             catch (OsmTransferException ex) {
    169                 dealWithTransferException(ex);
     122                if (useChangesets) api.stopChangeset();
     123            } catch (Exception ee) {
     124                // ignore nested exception
    170125            }
    171126            dealWithTransferException(e);
     
    173128    }
    174129
    175     /* FIXME: This code is terrible, please fix it!!!! */
    176 
    177     /* Ok, this needs some explanation: The problem is that the code for
    178      * retrying requests is intertwined with the code that generates the
    179      * actual request. This means that for the retry code for the
    180      * changeset stuff, it's basically a copy/cut/change slightly
    181      * process. What actually needs to happen is that the retrying needs
    182      * to be split from the creation of the requests and the retry loop
    183      * handled in one place (preferably without recursion). While at you
    184      * can fix the issue where hitting cancel doesn't do anything while
    185      * retrying. - Mv0 Apr 2008
    186      *
    187      * Cancelling has an effect now, maybe it does not always catch on. Florian Heer, Aug 08
    188      */
    189     private boolean startChangeset(int retries, String comment) throws OsmTransferException {
    190         Main.pleaseWaitDlg.currentAction.setText(tr("Opening changeset..."));
    191         changeset = new Changeset();
    192         changeset.put( "created_by", "JOSM" );
    193         changeset.put( "comment", comment );
    194         try {
    195             if (cancel)
    196                 return false; // assume cancel
    197             String version = Main.pref.get("osm-server.version", "0.6");
    198             URL url = new URL(
    199                     Main.pref.get("osm-server.url") +
    200                     "/" + version +
    201                     "/" + "changeset" +
    202                     "/" + "create");
    203             System.out.print("upload to: "+url+ "..." );
    204             activeConnection = (HttpURLConnection)url.openConnection();
    205             activeConnection.setConnectTimeout(15000);
    206             activeConnection.setRequestMethod("PUT");
    207             addAuth(activeConnection);
    208 
    209             activeConnection.setDoOutput(true);
    210             OutputStream out = activeConnection.getOutputStream();
    211             OsmWriter.output(out, changeset);
    212             out.close();
    213 
    214             activeConnection.connect();
    215             System.out.println("connected");
    216 
    217             int retCode = activeConnection.getResponseCode();
    218             if (retCode == 200)
    219                 changeset.id = readId(activeConnection.getInputStream());
    220             System.out.println("got return: "+retCode+" with id "+changeset.id);
    221             String retMsg = activeConnection.getResponseMessage();
    222             activeConnection.disconnect();
    223             if (retCode == 404)    {
    224                 throw new OsmTransferException(tr("Server does not support changesets"));
    225             }
    226             if (retCode != 200 && retCode != 412) {
    227                 if (retries >= 0) {
    228                     retries--;
    229                     if(sleepAndListen()) return false;
    230                     System.out.println("retrying ("+retries+" left)");
    231                     return startChangeset(retries, comment);
    232                 }
    233 
    234                 // Look for a detailed error message from the server
    235                 retMsg += "\n" + readString(activeConnection.getInputStream());
    236 
    237                 // Report our error
    238                 ByteArrayOutputStream o = new ByteArrayOutputStream();
    239                 OsmWriter.output(o, changeset);
    240                 System.out.println(new String(o.toByteArray(), "UTF-8").toString());
    241                 throw new OsmTransferException (retCode + " " + retMsg);
    242             }
    243         } catch (UnknownHostException e) {
    244             throw new OsmTransferException(tr("Unknown host")+": "+e.getMessage(), e);
    245         } catch(SocketTimeoutException e) {
    246             System.out.println(" timed out, retries left: " + retries);
    247             if (cancel)
    248                 return false; // assume cancel
    249             if (retries-- > 0)
    250                 startChangeset(retries, comment);
    251             else
    252                 throw new OsmTransferException (e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
    253         }
    254         catch (ConnectException e) {
    255             System.out.println(" timed out, retries left: " + retries);
    256             if (cancel)
    257                 return false; // assume cancel
    258             if (retries-- > 0)
    259                 startChangeset(retries, comment);
    260             else
    261                 throw new OsmTransferException (e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
    262         }
    263 
    264         catch (Exception e) {
    265             if (cancel)
    266                 return false; // assume cancel
    267             if (e instanceof OsmTransferException)
    268                 throw (OsmTransferException)e;
    269             if (e instanceof RuntimeException)
    270                 throw (RuntimeException)e;
    271             throw new RuntimeException(e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
    272         }
    273         return true;
    274     }
    275 
    276     private void uploadDiff(int retries, Collection<OsmPrimitive> list) throws OsmTransferException {
    277 
    278         CreateOsmChangeVisitor duv = new CreateOsmChangeVisitor(changeset);
    279 
    280         for (OsmPrimitive osm : list) {
    281             int progress = Main.pleaseWaitDlg.progress.getValue();
    282             Main.pleaseWaitDlg.currentAction.setText(tr("Preparing..."));
    283             if (cancel)
    284                 return;
    285             osm.visit(duv);
    286             Main.pleaseWaitDlg.progress.setValue(progress+1);
    287         }
    288         System.out.println("the document:\n");
    289         String diff = duv.getDocument();
    290         System.out.println(diff);
    291 
    292         Main.pleaseWaitDlg.currentAction.setText(tr("Uploading..."));
    293         try {
    294             if (cancel)
    295                 return; // assume cancel
    296             String version = Main.pref.get("osm-server.version", "0.6");
    297             URL url = new URL(
    298                     Main.pref.get("osm-server.url") +
    299                     "/" + version +
    300                     "/" + "changeset" +
    301                     "/" + changeset.id +
    302                     "/upload" );
    303             System.out.print("upload to: "+url+ "..." );
    304             activeConnection = (HttpURLConnection)url.openConnection();
    305             activeConnection.setConnectTimeout(15000);
    306             activeConnection.setRequestMethod("POST");
    307             addAuth(activeConnection);
    308 
    309             activeConnection.setDoOutput(true);
    310             PrintWriter out;
    311             try {
    312                 out = new PrintWriter(new OutputStreamWriter(activeConnection.getOutputStream(), "UTF-8"));
    313             } catch (UnsupportedEncodingException e) {
    314                 throw new RuntimeException(e);
    315             }
    316             out.print(diff);
    317             out.close();
    318 
    319             activeConnection.connect();
    320             System.out.println("connected");
    321 
    322             int retCode = activeConnection.getResponseCode();
    323             String retMsg = "";
    324 
    325             if (retCode == 200) {
    326                 DiffResultReader.parseDiffResult(activeConnection.getInputStream(), list, processed, duv.getNewIdMap(), Main.pleaseWaitDlg);
    327             } else if (retCode != 200 && retCode != 412) {
    328                 if (retries >= 0) {
    329                     retries--;
    330                     if(sleepAndListen()) return;
    331                     System.out.println("retrying ("+retries+" left)");
    332                     stopChangeset(retries);
    333                 } else {
    334                     // Look for a detailed error message from the server
    335                     retMsg += "\n" + readString(activeConnection.getInputStream());
    336 
    337                     // Report our error
    338                     ByteArrayOutputStream o = new ByteArrayOutputStream();
    339                     OsmWriter.output(o, changeset);
    340                     System.out.println(new String(o.toByteArray(), "UTF-8").toString());
    341                     throw new OsmTransferException(retCode+" "+retMsg);
    342                 }
    343             }
    344         } catch (UnknownHostException e) {
    345             throw new OsmTransferException(tr("Unknown host")+": "+e.getMessage(), e);
    346         } catch(SocketTimeoutException e) {
    347             System.out.println(" timed out, retries left: " + retries);
    348             if (cancel)
    349                 return; // assume cancel
    350             if (retries-- > 0)
    351                 stopChangeset(retries);
    352             else
    353                 throw new OsmTransferException(e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
    354         } catch(ConnectException e) {
    355             System.out.println(" timed out, retries left: " + retries);
    356             if (cancel)
    357                 return; // assume cancel
    358             if (retries-- > 0)
    359                 stopChangeset(retries);
    360             else
    361                 throw new OsmTransferException(e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
    362         } catch (Exception e) {
    363             if (cancel)
    364                 return; // assume cancel
    365             if (e instanceof OsmTransferException)
    366                 throw (OsmTransferException)e;
    367             if (e instanceof RuntimeException)
    368                 throw (RuntimeException)e;
    369             throw new RuntimeException(e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
    370         }
    371     }
    372 
    373 
    374     private void stopChangeset(int retries) throws OsmTransferException {
    375         Main.pleaseWaitDlg.currentAction.setText(tr("Closing changeset..."));
    376         try {
    377             if (cancel)
    378                 return; // assume cancel
    379             String version = Main.pref.get("osm-server.version", "0.6");
    380             URL url = new URL(
    381                     Main.pref.get("osm-server.url") +
    382                     "/" + version +
    383                     "/" + "changeset" +
    384                     "/" + changeset.id +
    385                     "/close" );
    386             System.out.print("upload to: "+url+ "..." );
    387             activeConnection = (HttpURLConnection)url.openConnection();
    388             activeConnection.setConnectTimeout(15000);
    389             activeConnection.setRequestMethod("PUT");
    390             addAuth(activeConnection);
    391 
    392             activeConnection.setDoOutput(true);
    393             OutputStream out = activeConnection.getOutputStream();
    394             OsmWriter.output(out, changeset);
    395             out.close();
    396 
    397             activeConnection.connect();
    398             System.out.println("connected");
    399 
    400             int retCode = activeConnection.getResponseCode();
    401             System.out.println("got return: "+retCode);
    402             String retMsg = activeConnection.getResponseMessage();
    403             activeConnection.disconnect();
    404             if (retCode == 404)    {
    405                 System.out.println("Server does not support changesets, or the changeset could not be found, continuing");
    406                 return;
    407             }
    408             if (retCode != 200 && retCode != 412) {
    409                 if (retries >= 0) {
    410                     retries--;
    411                     if(sleepAndListen()) return;
    412                     System.out.println("retrying ("+retries+" left)");
    413                     stopChangeset(retries);
    414                 } else {
    415                     // Look for a detailed error message from the server
    416                     retMsg += readString(activeConnection.getInputStream());
    417 
    418                     // Report our error
    419                     ByteArrayOutputStream o = new ByteArrayOutputStream();
    420                     OsmWriter.output(o, changeset);
    421                     System.out.println(new String(o.toByteArray(), "UTF-8").toString());
    422                     throw new OsmTransferException(retCode+" "+retMsg);
    423                 }
    424             }
    425         } catch (UnknownHostException e) {
    426             throw new OsmTransferException(tr("Unknown host")+": "+e.getMessage(), e);
    427         } catch(SocketTimeoutException e) {
    428             System.out.println(" timed out, retries left: " + retries);
    429             if (cancel)
    430                 return; // assume cancel
    431             if (retries-- > 0)
    432                 stopChangeset(retries);
    433             else
    434                 throw new OsmTransferException(e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
    435         } catch(ConnectException e) {
    436             System.out.println(" timed out, retries left: " + retries);
    437             if (cancel)
    438                 return; // assume cancel
    439             if (retries-- > 0)
    440                 stopChangeset(retries);
    441             else
    442                 throw new OsmTransferException(e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
    443         } catch (Exception e) {
    444             if (cancel)
    445                 return; // assume cancel
    446             if (e instanceof OsmTransferException)
    447                 throw (OsmTransferException)e;
    448             if (e instanceof RuntimeException)
    449                 throw (RuntimeException)e;
    450             throw new RuntimeException(e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
    451         }
    452     }
    453 
    454     private boolean sleepAndListen() {
    455         // System.out.print("backing off for 10 seconds...");
    456         for(int i=0; i < 10; i++) {
    457             if(cancel || isAuthCancelled()) {
    458                 if(!cancel) cancel();
    459                 return true;
    460             }
    461             try {
    462                 Thread.sleep(1000);
    463             } catch (InterruptedException ex) {}
    464         }
    465         return false;
    466     }
    467 
    468     /**
    469      * Upload a single node.
    470      */
    471     public void visit(Node n) {
    472         if (n.deleted) {
    473             sendRequest("DELETE", "node", n, true);
     130    void makeApiRequest(OsmPrimitive osm) throws OsmTransferException {
     131        if (osm.deleted) {
     132            api.deletePrimitive(osm);
     133        } else if (osm.id == 0) {
     134            api.createPrimitive(osm);
    474135        } else {
    475             sendRequest("PUT", "node", n, true);
    476         }
    477         processed.add(n);
    478     }
    479 
    480     /**
    481      * Upload a whole way with the complete node id list.
    482      */
    483     public void visit(Way w) {
    484         if (w.deleted) {
    485             sendRequest("DELETE", "way", w, true);
    486         } else {
    487             sendRequest("PUT", "way", w, true);
    488         }
    489         processed.add(w);
    490     }
    491 
    492     /**
    493      * Upload an relation with all members.
    494      */
    495     public void visit(Relation e) {
    496         if (e.deleted) {
    497             sendRequest("DELETE", "relation", e, true);
    498         } else {
    499             sendRequest("PUT", "relation", e, true);
    500         }
    501         processed.add(e);
    502     }
    503 
    504     /**
    505      * Read a long from the input stream and return it.
    506      */
    507     private long readId(InputStream inputStream) throws IOException {
    508         BufferedReader in = new BufferedReader(new InputStreamReader(
    509                 inputStream));
    510         String s = in.readLine();
    511         if (s == null)
    512             return 0;
    513         try {
    514             return Long.parseLong(s);
    515         } catch (NumberFormatException e) {
    516             return 0;
    517         }
    518     }
    519 
    520     /**
    521      * Consume the input stream and return it as a string.
    522      */
    523     private String readString(InputStream inputStream) throws IOException {
    524         BufferedReader in = new BufferedReader(new InputStreamReader(
    525                 inputStream));
    526         StringBuffer sb = new StringBuffer();
    527         String s;
    528         while((s = in.readLine()) != null) {
    529             sb.append(s);
    530             sb.append("\n");
    531         }
    532         return sb.toString();
    533     }
    534 
    535     /**
    536      * Send the request. The objects id will be replaced if it was 0 before
    537      * (on add requests).
    538      *
    539      * @param requestMethod The http method used when talking with the server.
    540      * @param urlSuffix The suffix to add at the server url.
    541      * @param osm The primitive to encode to the server.
    542      * @param body the body to be sent
    543      */
    544     private void sendRequestRetry(String requestMethod, String urlSuffix,
    545             OsmPrimitive osm, OsmWriterInterface body, int retries) throws OsmTransferException {
    546         try {
    547             if (cancel)
    548                 return; // assume cancel
    549             String version = Main.pref.get("osm-server.version", "0.5");
    550             URL url = new URL(
    551                     new URL(Main.pref.get("osm-server.url") +
    552                     "/" + version + "/"),
    553                     urlSuffix +
    554                     "/" + (osm.id==0 ? "create" : osm.id),
    555                     new MyHttpHandler());
    556             System.out.print("upload to: "+url+ "..." );
    557             activeConnection = (HttpURLConnection)url.openConnection();
    558             activeConnection.setConnectTimeout(15000);
    559             activeConnection.setRequestMethod(requestMethod);
    560             addAuth(activeConnection);
    561             if (body != null) {
    562                 activeConnection.setDoOutput(true);
    563                 OutputStream out = activeConnection.getOutputStream();
    564                 OsmWriter.output(out, body);
    565                 out.close();
    566             }
    567             activeConnection.connect();
    568             System.out.println("connected");
    569 
    570             int retCode = activeConnection.getResponseCode();
    571             /* When creating new, the returned value is the new id, otherwise it is the new version */
    572             if (retCode == 200)    {
    573                 if (osm.id == 0) {
    574                     osm.id = readId(activeConnection.getInputStream());
    575                     osm.version = 1;
    576                 } else {
    577                     int read_version = (int)readId(activeConnection.getInputStream());
    578                     if (read_version > 0)
    579                         osm.version = read_version;
    580                 }
    581             } else {
    582                 System.out.println("got return: "+retCode+" with id "+osm.id);
    583             }
    584             activeConnection.disconnect();
    585             if (retCode == 410 && requestMethod.equals("DELETE"))
    586                 return; // everything fine.. was already deleted.
    587             else if (retCode != 200) {
    588                 if (retries >= 0 && retCode != 412)    {
    589                     retries--;
    590                     if(sleepAndListen()) return;
    591                     System.out.println("retrying ("+retries+" left)");
    592                     sendRequestRetry(requestMethod, urlSuffix, osm, body, retries);
    593                 } else {
    594                     String retMsg = activeConnection.getResponseMessage();
    595                     // Look for a detailed error message from the server
    596                     if (activeConnection.getHeaderField("Error") != null)
    597                         retMsg += "\n" + activeConnection.getHeaderField("Error");
    598 
    599                     // Report our error
    600                     ByteArrayOutputStream o = new ByteArrayOutputStream();
    601                     OsmWriter.output(o, body);
    602                     System.out.println(new String(o.toByteArray(), "UTF-8").toString());
    603                     throw new OsmTransferException(retCode+" "+retMsg);
    604                 }
    605             }
    606         } catch (UnknownHostException e) {
    607             throw new OsmTransferException(tr("Unknown host")+": "+e.getMessage(), e);
    608         } catch(SocketTimeoutException e) {
    609             System.out.println(" timed out, retries left: " + retries);
    610             if (cancel)
    611                 return; // assume cancel
    612             if (retries-- > 0)
    613                 sendRequestRetry(requestMethod, urlSuffix, osm, body, retries);
    614             else
    615                 throw new OsmTransferException (e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
    616         } catch(ConnectException e) {
    617             System.out.println(" timed out, retries left: " + retries);
    618             if (cancel)
    619                 return; // assume cancel
    620             if (retries-- > 0)
    621                 sendRequestRetry(requestMethod, urlSuffix, osm, body, retries);
    622             else
    623                 throw new OsmTransferException (e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
    624         } catch (Exception e) {
    625             if (cancel)
    626                 return; // assume cancel
    627             if (e instanceof OsmTransferException)
    628                 throw (OsmTransferException)e;
    629             if (e instanceof RuntimeException)
    630                 throw (RuntimeException)e;
    631             throw new RuntimeException(e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
    632         }
    633     }
    634 
    635     private void sendRequest(String requestMethod, String urlSuffix,
    636             OsmPrimitive osm, boolean addBody)  {
    637         XmlWriter.OsmWriterInterface body = null;
    638         if (addBody) {
    639                 body = new OsmWriter.Single(osm, true, changeset);
    640         }
    641         try {
    642             sendRequestRetry(requestMethod, urlSuffix, osm, body, 10);
    643         }
    644         catch (OsmTransferException e) {
    645             dealWithTransferException (e);
     136            api.modifyPrimitive(osm);
    646137        }
    647138    }
     
    649140    private void dealWithTransferException (OsmTransferException e) {
    650141        Main.pleaseWaitDlg.currentAction.setText(tr("Transfer aborted due to error (will wait for 5 seconds):") + e.getMessage());
    651         cancel = true;
    652142        try {
    653143            Thread.sleep(5000);
  • trunk/src/org/openstreetmap/josm/io/OsmWriter.java

    r1499 r1523  
    66import java.util.Map.Entry;
    77
    8 import org.openstreetmap.josm.Main;
     8import org.openstreetmap.josm.data.osm.Changeset;
    99import org.openstreetmap.josm.data.osm.DataSet;
    1010import org.openstreetmap.josm.data.osm.DataSource;
     11import org.openstreetmap.josm.data.osm.Node;
     12import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1113import org.openstreetmap.josm.data.osm.Relation;
    1214import org.openstreetmap.josm.data.osm.RelationMember;
    13 import org.openstreetmap.josm.data.osm.Node;
    14 import org.openstreetmap.josm.data.osm.OsmPrimitive;
    15 import org.openstreetmap.josm.data.osm.Changeset;
    1615import org.openstreetmap.josm.data.osm.Way;
    1716import org.openstreetmap.josm.data.osm.visitor.Visitor;
     
    2625
    2726    /**
    28      * The counter for new created objects. Starting at -1 and goes down.
     27     * The counter for newly created objects. Starts at -1 and goes down.
    2928     */
    3029    private long newIdCounter = -1;
     30 
    3131    /**
    3232     * All newly created ids and their primitive that uses it. This is a back reference
     
    3535    public HashMap<OsmPrimitive, Long> usedNewIds = new HashMap<OsmPrimitive, Long>();
    3636
    37     private final boolean osmConform;
    38     private final Changeset changeset;
    39 
    40     public abstract static class Osm implements OsmWriterInterface {
    41         public void header(PrintWriter out) {
    42             out.print("<osm version='");
    43             out.print(Main.pref.get("osm-server.version", "0.5"));
    44             out.println("' generator='JOSM'>");
    45         }
    46         public void footer(PrintWriter out) {
    47             out.println("</osm>");
    48         }
    49     }
    50 
    51     // simple helper to write the object's class to the out stream
    52     private Visitor typeWriteVisitor = new Visitor() {
    53         public void visit(Node n) { out.print("node"); }
    54         public void visit(Way w) { out.print("way"); }
    55         public void visit(Relation e) { out.print("relation"); }
    56     };
    57 
    58     /**
    59      * An output writer for function output that writes everything of the given dataset into
    60      * the xml
    61      */
    62     public static final class All extends Osm {
    63         private final DataSet ds;
    64         private final boolean osmConform;
    65 
    66         /**
    67          * Construct an writer function
    68          * @param osmConform <code>true</code>, if the xml should be 100% osm conform. In this
    69          *      case, not all information can be retrieved later (as example, modified state
    70          *      is lost and id's remain 0 instead of decrementing from -1)
    71          */
    72         public All(DataSet ds, boolean osmConform) {
    73             this.ds = ds;
    74             this.osmConform = osmConform;
    75         }
    76 
    77         public void write(PrintWriter out) {
    78             Visitor writer = new OsmWriter(out, osmConform, null);
    79             for (Node n : ds.nodes)
    80                 if (shouldWrite(n))
    81                     writer.visit(n);
    82             for (Way w : ds.ways)
    83                 if (shouldWrite(w))
    84                     writer.visit(w);
    85             for (Relation e : ds.relations)
    86                 if (shouldWrite(e))
    87                     writer.visit(e);
    88         }
    89 
    90         private boolean shouldWrite(OsmPrimitive osm) {
    91             return osm.id != 0 || !osm.deleted;
    92         }
    93 
    94         @Override public void header(PrintWriter out) {
    95             super.header(out);
    96             for (DataSource s : ds.dataSources) {
    97                 out.println("  <bounds minlat='"
    98                 + s.bounds.min.lat()+"' minlon='"
    99                 + s.bounds.min.lon()+"' maxlat='"
    100                 + s.bounds.max.lat()+"' maxlon='"
    101                 + s.bounds.max.lon()
    102                 +"' origin='"+XmlWriter.encode(s.origin)+"' />");
    103             }
    104         }
    105     }
    106 
    107     /**
    108      * An output writer for functino output that writes only one specific primitive into
    109      * the xml
    110      */
    111     public static final class Single extends Osm {
    112         private final OsmPrimitive osm;
    113         private final boolean osmConform;
    114         private final Changeset changeset;
    115 
    116         public Single(OsmPrimitive osm, boolean osmConform, Changeset changeset) {
    117             this.osm = osm;
    118             this.osmConform = osmConform;
    119             this.changeset = changeset;
    120         }
    121 
    122         public void write(PrintWriter out) {
    123             osm.visit(new OsmWriter(out, osmConform, changeset));
    124         }
    125     }
    126 
    127     public OsmWriter(PrintWriter out, boolean osmConform, Changeset changeset) {
     37    private boolean osmConform;
     38    private boolean withBody = true;
     39    private String version;
     40    private Changeset changeset;
     41   
     42    public OsmWriter(PrintWriter out, boolean osmConform, String version) {
    12843        super(out);
    12944        this.osmConform = osmConform;
    130         this.changeset = changeset;
     45        this.version = version;
     46    }
     47   
     48    public void setWithBody(boolean wb) {
     49        this.withBody = wb;
     50    }
     51    public void setChangeset(Changeset cs) {
     52        this.changeset = cs;
     53    }
     54    public void setVersion(String v) {
     55        this.version = v;
     56    }
     57   
     58    public void header() {
     59        out.println("<?xml version='1.0' encoding='UTF-8'?>");
     60        out.print("<osm version='");
     61        out.print(version);
     62        out.println("' generator='JOSM'>");
     63    }
     64    public void footer() {
     65        out.println("</osm>");
     66    }
     67
     68    public void writeContent(DataSet ds) {
     69        for (Node n : ds.nodes)
     70            if (shouldWrite(n))
     71                visit(n);
     72        for (Way w : ds.ways)
     73            if (shouldWrite(w))
     74                visit(w);
     75        for (Relation e : ds.relations)
     76            if (shouldWrite(e))
     77                visit(e);
     78    }
     79
     80    private boolean shouldWrite(OsmPrimitive osm) {
     81        return osm.id != 0 || !osm.deleted;
     82    }
     83
     84    public void writeDataSources(DataSet ds) {
     85        for (DataSource s : ds.dataSources) {
     86            out.println("  <bounds minlat='"
     87                    + s.bounds.min.lat()+"' minlon='"
     88                    + s.bounds.min.lon()+"' maxlat='"
     89                    + s.bounds.max.lat()+"' maxlon='"
     90                    + s.bounds.max.lon()
     91                    +"' origin='"+XmlWriter.encode(s.origin)+"' />");
     92        }
    13193    }
    13294
     
    13597        addCommon(n, "node");
    13698        out.print(" lat='"+n.coor.lat()+"' lon='"+n.coor.lon()+"'");
    137         addTags(n, "node", true);
     99        if (!withBody) {
     100            out.println("/>"); 
     101        } else {
     102            addTags(n, "node", true);
     103        }
    138104    }
    139105
     
    141107        if (w.incomplete) return;
    142108        addCommon(w, "way");
    143         out.println(">");
    144         for (Node n : w.nodes)
    145             out.println("    <nd ref='"+getUsedId(n)+"' />");
    146         addTags(w, "way", false);
     109        if (!withBody) {
     110            out.println("/>"); 
     111        } else {
     112            out.println(">");
     113            for (Node n : w.nodes)
     114                out.println("    <nd ref='"+getUsedId(n)+"' />");
     115            addTags(w, "way", false);
     116        }
    147117    }
    148118
     
    150120        if (e.incomplete) return;
    151121        addCommon(e, "relation");
    152         out.println(">");
    153         for (RelationMember em : e.members) {
    154             out.print("    <member type='");
    155             em.member.visit(typeWriteVisitor);
    156             out.println("' ref='"+getUsedId(em.member)+"' role='" +
    157                 XmlWriter.encode(em.role) + "' />");
    158         }
    159         addTags(e, "relation", false);
    160     }
    161 
     122        if (!withBody) {
     123            out.println("/>"); 
     124        } else {
     125            out.println(">");
     126            for (RelationMember em : e.members) {
     127                out.print("    <member type='");
     128                out.print(OsmApi.which(em.member));
     129                out.println("' ref='"+getUsedId(em.member)+"' role='" +
     130                        XmlWriter.encode(em.role) + "' />");
     131            }
     132            addTags(e, "relation", false);
     133        }
     134    }
     135
     136    public void visit(Changeset cs) {
     137        addCommon(cs, "changeset");
     138        out.println(">\n");
     139        addTags(cs, "changeset", false);
     140    }
     141
     142    public final void footer(PrintWriter out) {
     143        out.println("</osm>");
     144    }
    162145
    163146    /**
     
    192175     */
    193176    private void addCommon(OsmPrimitive osm, String tagname) {
    194         out.print("  <"+tagname+" id='"+getUsedId(osm)+"'");
     177        long id = getUsedId(osm);
     178        out.print("  <"+tagname);
     179        if (id != 0) {
     180             out.print(" id='"+getUsedId(osm)+"'");
     181        }
    195182        if (!osmConform) {
    196183            String action = null;
  • trunk/src/org/openstreetmap/josm/io/XmlWriter.java

    r1169 r1523  
    22package org.openstreetmap.josm.io;
    33
    4 import java.io.OutputStream;
    5 import java.io.OutputStreamWriter;
    64import java.io.PrintWriter;
    7 import java.io.UnsupportedEncodingException;
    85import java.util.HashMap;
    96
     
    1512public class XmlWriter {
    1613
    17     /**
    18      * The interface to write the data into an Osm stream
    19      * @author immanuel.scholz
    20      */
    21     public static interface OsmWriterInterface {
    22         void header(PrintWriter out);
    23         void write(PrintWriter out);
    24         void footer(PrintWriter out);
    25     }
    26 
    27 
    28     protected XmlWriter(PrintWriter out) {
     14    protected PrintWriter out;
     15   
     16    public XmlWriter(PrintWriter out) {
    2917        this.out = out;
    3018    }
    31 
     19   
    3220    /**
    3321     * Encode the given string in XML1.0 format.
     
    4937
    5038    /**
    51      * Write the header and start tag, then call the runnable to add all real tags and finally
    52      * "closes" the xml by writing the footer.
    53      */
    54     public static void output(OutputStream outStream, OsmWriterInterface outputWriter) {
    55         PrintWriter out;
    56         try {
    57             out = new PrintWriter(new OutputStreamWriter(outStream, "UTF-8"));
    58         } catch (UnsupportedEncodingException e) {
    59             throw new RuntimeException(e);
    60         }
    61         out.println("<?xml version='1.0' encoding='UTF-8'?>");
    62         outputWriter.header(out);
    63         outputWriter.write(out);
    64         outputWriter.footer(out);
    65         out.flush();
    66         out.close();
    67     }
    68 
    69     /**
    7039     * The output writer to save the values to.
    7140     */
    72     protected final PrintWriter out;
    7341    final private static HashMap<Character, String> encoding = new HashMap<Character, String>();
    7442    static {
Note: See TracChangeset for help on using the changeset viewer.