1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.util.xml;
16  
17  import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayOutputStream;
18  import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
19  import com.liferay.portal.kernel.util.StringPool;
20  import com.liferay.portal.kernel.util.StringUtil;
21  import com.liferay.portal.kernel.util.Validator;
22  
23  import java.io.IOException;
24  
25  import org.dom4j.Branch;
26  import org.dom4j.Document;
27  import org.dom4j.DocumentException;
28  import org.dom4j.io.OutputFormat;
29  import org.dom4j.io.SAXReader;
30  import org.dom4j.io.XMLWriter;
31  
32  /**
33   * <a href="XMLFormatter.java.html"><b><i>View Source</i></b></a>
34   *
35   * @author Brian Wing Shun Chan
36   * @author Alan Zimmerman
37   */
38  public class XMLFormatter {
39  
40      public static String fixProlog(String xml) {
41  
42          // LEP-1921
43  
44          if (xml != null) {
45              char[] charArray = xml.toCharArray();
46  
47              for (int i = 0; i < charArray.length; i++) {
48                  if (charArray[i] == '<') {
49                      if (i != 0) {
50                          xml = xml.substring(i, xml.length());
51                      }
52  
53                      break;
54                  }
55              }
56          }
57  
58          return xml;
59      }
60  
61      public static String fromCompactSafe(String xml) {
62          return StringUtil.replace(xml, "[$NEW_LINE$]", StringPool.NEW_LINE);
63      }
64  
65      public static String stripInvalidChars(String xml) {
66          if (Validator.isNull(xml)) {
67              return xml;
68          }
69  
70          // Strip characters that are not valid in the 1.0 XML spec
71          // http://www.w3.org/TR/2000/REC-xml-20001006#NT-Char
72  
73          StringBuilder sb = new StringBuilder();
74  
75          for (int i = 0; i < xml.length(); i++) {
76              char c = xml.charAt(i);
77  
78              if ((c == 0x9) || (c == 0xA) || (c == 0xD) ||
79                  ((c >= 0x20) && (c <= 0xD7FF)) ||
80                  ((c >= 0xE000) && (c <= 0xFFFD)) ||
81                  ((c >= 0x10000) && (c <= 0x10FFFF))) {
82  
83                  sb.append(c);
84              }
85          }
86  
87          return sb.toString();
88      }
89  
90      public static String toCompactSafe(String xml) {
91          return StringUtil.replace(
92              xml,
93              new String[] {
94                  StringPool.RETURN_NEW_LINE,
95                  StringPool.NEW_LINE,
96                  StringPool.RETURN
97              },
98              new String[] {
99                  "[$NEW_LINE$]",
100                 "[$NEW_LINE$]",
101                 "[$NEW_LINE$]"
102             });
103     }
104 
105     public static String toString(Branch branch) throws IOException {
106         return toString(branch, StringPool.TAB);
107     }
108 
109     public static String toString(Branch branch, String indent)
110         throws IOException {
111 
112         return toString(branch, StringPool.TAB, false);
113     }
114 
115     public static String toString(
116             Branch branch, String indent, boolean expandEmptyElements)
117         throws IOException {
118 
119         UnsyncByteArrayOutputStream unsyncByteArrayOutputStream =
120             new UnsyncByteArrayOutputStream();
121 
122         OutputFormat outputFormat = OutputFormat.createPrettyPrint();
123 
124         outputFormat.setExpandEmptyElements(expandEmptyElements);
125         outputFormat.setIndent(indent);
126         outputFormat.setLineSeparator(StringPool.NEW_LINE);
127 
128         XMLWriter writer = new XMLWriter(
129             unsyncByteArrayOutputStream, outputFormat);
130 
131         writer.write(branch);
132 
133         String content = unsyncByteArrayOutputStream.toString(StringPool.UTF8);
134 
135         // LEP-4257
136 
137         //content = StringUtil.replace(content, "\n\n\n", "\n\n");
138 
139         if (content.endsWith("\n\n")) {
140             content = content.substring(0, content.length() - 2);
141         }
142 
143         if (content.endsWith("\n")) {
144             content = content.substring(0, content.length() - 1);
145         }
146 
147         while (content.indexOf(" \n") != -1) {
148             content = StringUtil.replace(content, " \n", "\n");
149         }
150 
151         return content;
152     }
153 
154     public static String toString(String xml)
155         throws DocumentException, IOException {
156 
157         return toString(xml, StringPool.TAB);
158     }
159 
160     public static String toString(String xml, String indent)
161         throws DocumentException, IOException {
162 
163         SAXReader reader = new SAXReader();
164 
165         Document doc = reader.read(new UnsyncStringReader(xml));
166 
167         return toString(doc, indent);
168     }
169 
170 }