001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.util.xml;
016    
017    import com.liferay.portal.kernel.exception.SystemException;
018    import com.liferay.portal.kernel.util.CharPool;
019    import com.liferay.portal.kernel.util.StringPool;
020    import com.liferay.portal.kernel.util.StringUtil;
021    import com.liferay.portal.kernel.util.Validator;
022    import com.liferay.portal.kernel.xml.Document;
023    
024    import java.io.IOException;
025    
026    /**
027     * @author Leonardo Barros
028     * @see com.liferay.petra.xml.XMLUtil
029     */
030    public class XMLUtil {
031    
032            public static String fixProlog(String xml) {
033    
034                    // LEP-1921
035    
036                    if (xml != null) {
037                            int pos = xml.indexOf(CharPool.LESS_THAN);
038    
039                            if (pos > 0) {
040                                    xml = xml.substring(pos);
041                            }
042                    }
043    
044                    return xml;
045            }
046    
047            public static String formatXML(Document document) {
048                    try {
049                            return document.formattedString(_XML_INDENT);
050                    }
051                    catch (IOException ioe) {
052                            throw new SystemException(ioe);
053                    }
054            }
055    
056            public static String formatXML(String xml) {
057    
058                    // This is only supposed to format your xml, however, it will also
059                    // unwantingly change © and other characters like it into their
060                    // respective readable versions
061    
062                    try {
063                            xml = StringUtil.replace(xml, "&#", "[$SPECIAL_CHARACTER$]");
064                            xml = Dom4jUtil.toString(xml, _XML_INDENT);
065                            xml = StringUtil.replace(xml, "[$SPECIAL_CHARACTER$]", "&#");
066    
067                            return xml;
068                    }
069                    catch (IOException ioe) {
070                            throw new SystemException(ioe);
071                    }
072                    catch (org.dom4j.DocumentException de) {
073                            throw new SystemException(de);
074                    }
075            }
076    
077            public static String fromCompactSafe(String xml) {
078                    return StringUtil.replace(xml, "[$NEW_LINE$]", StringPool.NEW_LINE);
079            }
080    
081            public static String stripInvalidChars(String xml) {
082                    if (Validator.isNull(xml)) {
083                            return xml;
084                    }
085    
086                    // Strip characters that are not valid in the 1.0 XML spec
087                    // http://www.w3.org/TR/2000/REC-xml-20001006#NT-Char
088    
089                    StringBuilder sb = new StringBuilder();
090    
091                    for (int i = 0; i < xml.length(); i++) {
092                            char c = xml.charAt(i);
093    
094                            if ((c == 0x9) || (c == 0xA) || (c == 0xD) ||
095                                    ((c >= 0x20) && (c <= 0xD7FF)) ||
096                                    ((c >= 0xE000) && (c <= 0xFFFD)) ||
097                                    ((c >= 0x10000) && (c <= 0x10FFFF))) {
098    
099                                    sb.append(c);
100                            }
101                    }
102    
103                    return sb.toString();
104            }
105    
106            public static String toCompactSafe(String xml) {
107                    return StringUtil.replace(
108                            xml,
109                            new String[] {
110                                    StringPool.RETURN_NEW_LINE, StringPool.NEW_LINE,
111                                    StringPool.RETURN
112                            },
113                            new String[] {"[$NEW_LINE$]", "[$NEW_LINE$]", "[$NEW_LINE$]"});
114            }
115    
116            private static final String _XML_INDENT = "  ";
117    
118    }