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     */
029    public class XMLUtil {
030    
031            public static String fixProlog(String xml) {
032    
033                    // LEP-1921
034    
035                    if (xml != null) {
036                            int pos = xml.indexOf(CharPool.LESS_THAN);
037    
038                            if (pos > 0) {
039                                    xml = xml.substring(pos);
040                            }
041                    }
042    
043                    return xml;
044            }
045    
046            public static String formatXML(Document document) {
047                    try {
048                            return document.formattedString(_XML_INDENT);
049                    }
050                    catch (IOException ioe) {
051                            throw new SystemException(ioe);
052                    }
053            }
054    
055            public static String formatXML(String xml) {
056    
057                    // This is only supposed to format your xml, however, it will also
058                    // unwantingly change © and other characters like it into their
059                    // respective readable versions
060    
061                    try {
062                            xml = StringUtil.replace(xml, "&#", "[$SPECIAL_CHARACTER$]");
063                            xml = Dom4jUtil.toString(xml, _XML_INDENT);
064                            xml = StringUtil.replace(xml, "[$SPECIAL_CHARACTER$]", "&#");
065    
066                            return xml;
067                    }
068                    catch (IOException ioe) {
069                            throw new SystemException(ioe);
070                    }
071                    catch (org.dom4j.DocumentException de) {
072                            throw new SystemException(de);
073                    }
074            }
075    
076            public static String fromCompactSafe(String xml) {
077                    return StringUtil.replace(xml, "[$NEW_LINE$]", StringPool.NEW_LINE);
078            }
079    
080            public static String stripInvalidChars(String xml) {
081                    if (Validator.isNull(xml)) {
082                            return xml;
083                    }
084    
085                    // Strip characters that are not valid in the 1.0 XML spec
086                    // http://www.w3.org/TR/2000/REC-xml-20001006#NT-Char
087    
088                    StringBuilder sb = new StringBuilder();
089    
090                    for (int i = 0; i < xml.length(); i++) {
091                            char c = xml.charAt(i);
092    
093                            if ((c == 0x9) || (c == 0xA) || (c == 0xD) ||
094                                    ((c >= 0x20) && (c <= 0xD7FF)) ||
095                                    ((c >= 0xE000) && (c <= 0xFFFD)) ||
096                                    ((c >= 0x10000) && (c <= 0x10FFFF))) {
097    
098                                    sb.append(c);
099                            }
100                    }
101    
102                    return sb.toString();
103            }
104    
105            public static String toCompactSafe(String xml) {
106                    return StringUtil.replace(
107                            xml,
108                            new String[] {
109                                    StringPool.RETURN_NEW_LINE, StringPool.NEW_LINE,
110                                    StringPool.RETURN
111                            },
112                            new String[] {"[$NEW_LINE$]", "[$NEW_LINE$]", "[$NEW_LINE$]"});
113            }
114    
115            private static final String _XML_INDENT = "  ";
116    
117    }