001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.io; 003 004import java.io.Closeable; 005import java.io.IOException; 006import java.io.PrintWriter; 007import java.util.HashMap; 008import java.util.Map; 009 010/** 011 * Helper class to use for xml outputting classes. 012 * 013 * @author imi 014 */ 015public class XmlWriter implements Closeable { 016 017 protected final PrintWriter out; 018 019 public XmlWriter(PrintWriter out) { 020 this.out = out; 021 } 022 023 /** 024 * Flushes the stream. 025 */ 026 public void flush() { 027 if (out != null) { 028 out.flush(); 029 } 030 } 031 032 public static String encode(String unencoded) { 033 return encode(unencoded, false); 034 } 035 036 /** 037 * Encode the given string in XML1.0 format. 038 * Optimized to fast pass strings that don't need encoding (normal case). 039 * 040 * @param unencoded the unencoded input string 041 * @param keepApos true if apostrophe sign should stay as it is (in order to work around 042 * a Java bug that renders 043 * new JLabel("<html>&apos;</html>") 044 * literally as 6 character string, see #7558) 045 */ 046 public static String encode(String unencoded, boolean keepApos) { 047 StringBuilder buffer = null; 048 for (int i = 0; i < unencoded.length(); ++i) { 049 String encS = null; 050 if (!keepApos || unencoded.charAt(i) != '\'') { 051 encS = XmlWriter.encoding.get(unencoded.charAt(i)); 052 } 053 if (encS != null) { 054 if (buffer == null) { 055 buffer = new StringBuilder(unencoded.substring(0,i)); 056 } 057 buffer.append(encS); 058 } else if (buffer != null) { 059 buffer.append(unencoded.charAt(i)); 060 } 061 } 062 return (buffer == null) ? unencoded : buffer.toString(); 063 } 064 065 /** 066 * The output writer to save the values to. 067 */ 068 private static final Map<Character, String> encoding = new HashMap<>(); 069 static { 070 encoding.put('<', "<"); 071 encoding.put('>', ">"); 072 encoding.put('"', """); 073 encoding.put('\'', "'"); 074 encoding.put('&', "&"); 075 encoding.put('\n', "
"); 076 encoding.put('\r', "
"); 077 encoding.put('\t', "	"); 078 } 079 080 @Override 081 public void close() throws IOException { 082 if (out != null) { 083 out.close(); 084 } 085 } 086}