1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    *
5    *
6    *
7    * The contents of this file are subject to the terms of the Liferay Enterprise
8    * Subscription License ("License"). You may not use this file except in
9    * compliance with the License. You can obtain a copy of the License by
10   * contacting Liferay, Inc. See the License for the specific language governing
11   * permissions and limitations under the License, including but not limited to
12   * distribution rights of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.util.xml;
24  
25  import com.liferay.portal.kernel.util.ByteArrayMaker;
26  import com.liferay.portal.kernel.util.StringPool;
27  import com.liferay.portal.kernel.util.StringUtil;
28  import com.liferay.portal.kernel.util.Validator;
29  
30  import java.io.IOException;
31  import java.io.StringReader;
32  
33  import org.dom4j.Branch;
34  import org.dom4j.Document;
35  import org.dom4j.DocumentException;
36  import org.dom4j.io.OutputFormat;
37  import org.dom4j.io.SAXReader;
38  import org.dom4j.io.XMLWriter;
39  
40  /**
41   * <a href="XMLFormatter.java.html"><b><i>View Source</i></b></a>
42   *
43   * @author Brian Wing Shun Chan
44   * @author Alan Zimmerman
45   */
46  public class XMLFormatter {
47  
48      public static String fixProlog(String xml) {
49  
50          // LEP-1921
51  
52          if (xml != null) {
53              char[] charArray = xml.toCharArray();
54  
55              for (int i = 0; i < charArray.length; i++) {
56                  if (charArray[i] == '<') {
57                      if (i != 0) {
58                          xml = xml.substring(i, xml.length());
59                      }
60  
61                      break;
62                  }
63              }
64          }
65  
66          return xml;
67      }
68  
69      public static String fromCompactSafe(String xml) {
70          return StringUtil.replace(xml, "[$NEW_LINE$]", StringPool.NEW_LINE);
71      }
72  
73      public static String stripInvalidChars(String xml) {
74          if (Validator.isNull(xml)) {
75              return xml;
76          }
77  
78          // Strip characters that are not valid in the 1.0 XML spec
79          // http://www.w3.org/TR/2000/REC-xml-20001006#NT-Char
80  
81          StringBuilder sb = new StringBuilder();
82  
83          for (int i = 0; i < xml.length(); i++) {
84              char c = xml.charAt(i);
85  
86              if ((c == 0x9) || (c == 0xA) || (c == 0xD) ||
87                  ((c >= 0x20) && (c <= 0xD7FF)) ||
88                  ((c >= 0xE000) && (c <= 0xFFFD)) ||
89                  ((c >= 0x10000) && (c <= 0x10FFFF))) {
90  
91                  sb.append(c);
92              }
93          }
94  
95          return sb.toString();
96      }
97  
98      public static String toCompactSafe(String xml) {
99          return StringUtil.replace(
100             xml,
101             new String[] {
102                 StringPool.RETURN_NEW_LINE,
103                 StringPool.NEW_LINE,
104                 StringPool.RETURN
105             },
106             new String[] {
107                 "[$NEW_LINE$]",
108                 "[$NEW_LINE$]",
109                 "[$NEW_LINE$]"
110             });
111     }
112 
113     public static String toString(Branch branch) throws IOException {
114         return toString(branch, StringPool.TAB);
115     }
116 
117     public static String toString(Branch branch, String indent)
118         throws IOException {
119 
120         return toString(branch, StringPool.TAB, false);
121     }
122 
123     public static String toString(
124             Branch branch, String indent, boolean expandEmptyElements)
125         throws IOException {
126 
127         ByteArrayMaker bam = new ByteArrayMaker();
128 
129         OutputFormat format = OutputFormat.createPrettyPrint();
130 
131         format.setExpandEmptyElements(expandEmptyElements);
132         format.setIndent(indent);
133         format.setLineSeparator("\n");
134 
135         XMLWriter writer = new XMLWriter(bam, format);
136 
137         writer.write(branch);
138 
139         String content = bam.toString(StringPool.UTF8);
140 
141         // LEP-4257
142 
143         //content = StringUtil.replace(content, "\n\n\n", "\n\n");
144 
145         if (content.endsWith("\n\n")) {
146             content = content.substring(0, content.length() - 2);
147         }
148 
149         if (content.endsWith("\n")) {
150             content = content.substring(0, content.length() - 1);
151         }
152 
153         while (content.indexOf(" \n") != -1) {
154             content = StringUtil.replace(content, " \n", "\n");
155         }
156 
157         return content;
158     }
159 
160     public static String toString(String xml)
161         throws DocumentException, IOException {
162 
163         return toString(xml, StringPool.TAB);
164     }
165 
166     public static String toString(String xml, String indent)
167         throws DocumentException, IOException {
168 
169         SAXReader reader = new SAXReader();
170 
171         Document doc = reader.read(new StringReader(xml));
172 
173         return toString(doc, indent);
174     }
175 
176 }