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 }