001 // License: GPL. For details, see LICENSE file.
002 package org.openstreetmap.josm.io;
003
004 import static org.openstreetmap.josm.tools.I18n.tr;
005
006 import java.io.PrintWriter;
007 import java.io.StringWriter;
008 import java.util.Collection;
009
010 import org.openstreetmap.josm.data.osm.Changeset;
011 import org.openstreetmap.josm.data.osm.IPrimitive;
012
013 /**
014 * Creates an OsmChange document from JOSM edits.
015 * See http://wiki.openstreetmap.org/index.php/OsmChange for a documentation of the
016 * OsmChange format.
017 *
018 */
019 public class OsmChangeBuilder {
020 static public final String DEFAULT_API_VERSION = "0.6";
021
022 private String currentMode;
023 private PrintWriter writer;
024 private StringWriter swriter;
025 private OsmWriter osmwriter;
026 private String apiVersion = DEFAULT_API_VERSION;
027 private boolean prologWritten = false;
028
029 public OsmChangeBuilder(Changeset changeset) {
030 this(changeset, null /* default api version */);
031 }
032
033 public OsmChangeBuilder(Changeset changeset, String apiVersion) {
034 this.apiVersion = apiVersion == null ? DEFAULT_API_VERSION : apiVersion;
035 writer = new PrintWriter(swriter = new StringWriter());
036 osmwriter = OsmWriterFactory.createOsmWriter(writer, false, apiVersion);
037 osmwriter.setChangeset(changeset);
038 }
039
040 protected void write(IPrimitive p) {
041 if (p.isDeleted()) {
042 switchMode("delete");
043 osmwriter.setWithBody(false);
044 p.visit(osmwriter);
045 } else {
046 switchMode(p.isNew() ? "create" : "modify");
047 osmwriter.setWithBody(true);
048 p.visit(osmwriter);
049 }
050 }
051
052 private void switchMode(String newMode) {
053 if ((newMode != null && !newMode.equals(currentMode))||(newMode == null && currentMode != null)) {
054 if (currentMode != null) {
055 writer.print("</");
056 writer.print(currentMode);
057 writer.println(">");
058 }
059 if (newMode != null) {
060 writer.print("<");
061 writer.print(newMode);
062 writer.println(">");
063 }
064 currentMode = newMode;
065 }
066 }
067
068 /**
069 * Writes the prolog of the OsmChange document
070 *
071 * @throws IllegalStateException thrown if the prologs has already been written
072 */
073 public void start() throws IllegalStateException{
074 if (prologWritten)
075 throw new IllegalStateException(tr("Prolog of OsmChange document already written. Please write only once."));
076 writer.print("<osmChange version=\"");
077 writer.print(apiVersion);
078 writer.println("\" generator=\"JOSM\">");
079 prologWritten=true;
080 }
081
082 /**
083 * Appends a collection of Primitives to the OsmChange document.
084 *
085 * @param primitives the collection of primitives. Ignored if null.
086 * @throws IllegalStateException thrown if the prologs has not been written yet
087 * @see #start()
088 * @see #append(IPrimitive)
089 */
090 public void append(Collection<? extends IPrimitive> primitives) throws IllegalStateException{
091 if (primitives == null) return;
092 if (!prologWritten)
093 throw new IllegalStateException(tr("Prolog of OsmChange document not written yet. Please write first."));
094 for (IPrimitive p : primitives) {
095 write(p);
096 }
097 }
098
099 /**
100 * Appends an Primitive to the OsmChange document.
101 *
102 * @param p the primitive. Ignored if null.
103 * @throws IllegalStateException thrown if the prologs has not been written yet
104 * @see #start()
105 * @see #append(Collection)
106
107 */
108 public void append(IPrimitive p) {
109 if (p == null) return;
110 if (!prologWritten)
111 throw new IllegalStateException(tr("Prolog of OsmChange document not written yet. Please write first."));
112 write(p);
113 }
114
115 /**
116 * Writes the epilog of the OsmChange document
117 *
118 * @throws IllegalStateException thrown if the prologs has not been written yet
119 */
120 public void finish() throws IllegalStateException {
121 if (!prologWritten)
122 throw new IllegalStateException(tr("Prolog of OsmChange document not written yet. Please write first."));
123 if (currentMode != null) {
124 writer.print("</");
125 writer.print(currentMode);
126 writer.println(">");
127 }
128 writer.println("</osmChange>");
129 }
130
131 public String getDocument() {
132 return swriter.toString();
133 }
134 }