001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.io;
003
004import java.io.BufferedWriter;
005import java.io.OutputStream;
006import java.io.OutputStreamWriter;
007import java.io.PrintWriter;
008import java.nio.charset.StandardCharsets;
009import java.text.SimpleDateFormat;
010import java.util.Locale;
011
012import org.openstreetmap.josm.data.notes.Note;
013import org.openstreetmap.josm.data.notes.NoteComment;
014import org.openstreetmap.josm.data.osm.NoteData;
015import org.openstreetmap.josm.data.osm.User;
016
017/**
018 * Class to write a collection of notes out to XML.
019 * The format is that of the note dump file with the addition of one
020 * attribute in the comment element to indicate if the comment is a new local
021 * comment that has not been uploaded to the OSM server yet.
022 */
023public class NoteWriter extends XmlWriter {
024
025    private final SimpleDateFormat ISO8601_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX", Locale.ENGLISH);
026
027    /**
028     * Create a NoteWriter that will write to the given PrintWriter
029     * @param out PrintWriter to write XML to
030     */
031    public NoteWriter(PrintWriter out) {
032        super(out);
033    }
034
035    /**
036     * Create a NoteWriter that will write to a given OutputStream.
037     * @param out OutputStream to write XML to
038     */
039    public NoteWriter(OutputStream out) {
040        super(new PrintWriter(new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8))));
041    }
042
043    /**
044     * Write notes to designated output target
045     * @param data Note collection to write
046     */
047    public void write(NoteData data) {
048        out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
049        out.println("<osm-notes>");
050        for (Note note : data.getNotes()) {
051            out.print("  <note ");
052            out.print("id=\"" + note.getId() + "\" ");
053            out.print("lat=\"" + note.getLatLon().lat() + "\" ");
054            out.print("lon=\"" + note.getLatLon().lon() + "\" ");
055            out.print("created_at=\"" + ISO8601_FORMAT.format(note.getCreatedAt()) + "\" ");
056            if (note.getClosedAt() != null) {
057                out.print("closed_at=\"" + ISO8601_FORMAT.format(note.getClosedAt()) + "\" ");
058            }
059
060            out.println(">");
061            for (NoteComment comment : note.getComments()) {
062                writeComment(comment);
063            }
064            out.println("  </note>");
065        }
066
067        out.println("</osm-notes>");
068        out.flush();
069    }
070
071    private void writeComment(NoteComment comment) {
072        out.print("    <comment");
073        out.print(" action=\"" + comment.getNoteAction() + "\" ");
074        out.print("timestamp=\"" + ISO8601_FORMAT.format(comment.getCommentTimestamp()) + "\" ");
075        if (comment.getUser() != null && !comment.getUser().equals(User.getAnonymous())) {
076            out.print("uid=\"" + comment.getUser().getId() + "\" ");
077            out.print("user=\"" + encode(comment.getUser().getName()) + "\" ");
078        }
079        out.print("is_new=\"" + comment.getIsNew() + "\" ");
080        out.print(">");
081        out.print(encode(comment.getText(), false));
082        out.println("</comment>");
083    }
084}