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