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.CharPool;
20  import com.liferay.portal.kernel.util.StringPool;
21  import com.liferay.portal.kernel.util.StringUtil;
22  import com.liferay.portal.kernel.util.Validator;
23  
24  import java.io.IOException;
25  
26  import org.dom4j.Branch;
27  import org.dom4j.Document;
28  import org.dom4j.DocumentException;
29  import org.dom4j.io.OutputFormat;
30  import org.dom4j.io.SAXReader;
31  import org.dom4j.io.XMLWriter;
32  
33  /**
34   * <a href="XMLFormatter.java.html"><b><i>View Source</i></b></a>
35   *
36   * @author Brian Wing Shun Chan
37   * @author Alan Zimmerman
38   */
39  public class XMLFormatter {
40  
41      public static String fixProlog(String xml) {
42  
43          // LEP-1921
44  
45          if (xml != null) {
46              int pos = xml.indexOf(CharPool.LESS_THAN);
47  
48              if (pos > 0) {
49                  xml = xml.substring(pos);
50              }
51          }
52  
53          return xml;
54      }
55  
56      public static String fromCompactSafe(String xml) {
57          return StringUtil.replace(xml, "[$NEW_LINE$]", StringPool.NEW_LINE);
58      }
59  
60      public static String stripInvalidChars(String xml) {
61          if (Validator.isNull(xml)) {
62              return xml;
63          }
64  
65          // Strip characters that are not valid in the 1.0 XML spec
66          // http://www.w3.org/TR/2000/REC-xml-20001006#NT-Char
67  
68          StringBuilder sb = new StringBuilder();
69  
70          for (int i = 0; i < xml.length(); i++) {
71              char c = xml.charAt(i);
72  
73              if ((c == 0x9) || (c == 0xA) || (c == 0xD) ||
74                  ((c >= 0x20) && (c <= 0xD7FF)) ||
75                  ((c >= 0xE000) && (c <= 0xFFFD)) ||
76                  ((c >= 0x10000) && (c <= 0x10FFFF))) {
77  
78                  sb.append(c);
79              }
80          }
81  
82          return sb.toString();
83      }
84  
85      public static String toCompactSafe(String xml) {
86          return StringUtil.replace(
87              xml,
88              new String[] {
89                  StringPool.RETURN_NEW_LINE,
90                  StringPool.NEW_LINE,
91                  StringPool.RETURN
92              },
93              new String[] {
94                  "[$NEW_LINE$]",
95                  "[$NEW_LINE$]",
96                  "[$NEW_LINE$]"
97              });
98      }
99  
100     public static String toString(Branch branch) throws IOException {
101         return toString(branch, StringPool.TAB);
102     }
103 
104     public static String toString(Branch branch, String indent)
105         throws IOException {
106 
107         return toString(branch, StringPool.TAB, false);
108     }
109 
110     public static String toString(
111             Branch branch, String indent, boolean expandEmptyElements)
112         throws IOException {
113 
114         UnsyncByteArrayOutputStream unsyncByteArrayOutputStream =
115             new UnsyncByteArrayOutputStream();
116 
117         OutputFormat outputFormat = OutputFormat.createPrettyPrint();
118 
119         outputFormat.setExpandEmptyElements(expandEmptyElements);
120         outputFormat.setIndent(indent);
121         outputFormat.setLineSeparator(StringPool.NEW_LINE);
122 
123         XMLWriter writer = new XMLWriter(
124             unsyncByteArrayOutputStream, outputFormat);
125 
126         writer.write(branch);
127 
128         String content = unsyncByteArrayOutputStream.toString(StringPool.UTF8);
129 
130         // LEP-4257
131 
132         //content = StringUtil.replace(content, "\n\n\n", "\n\n");
133 
134         if (content.endsWith("\n\n")) {
135             content = content.substring(0, content.length() - 2);
136         }
137 
138         if (content.endsWith("\n")) {
139             content = content.substring(0, content.length() - 1);
140         }
141 
142         while (content.indexOf(" \n") != -1) {
143             content = StringUtil.replace(content, " \n", "\n");
144         }
145 
146         return content;
147     }
148 
149     public static String toString(String xml)
150         throws DocumentException, IOException {
151 
152         return toString(xml, StringPool.TAB);
153     }
154 
155     public static String toString(String xml, String indent)
156         throws DocumentException, IOException {
157 
158         SAXReader reader = new SAXReader();
159 
160         Document doc = reader.read(new UnsyncStringReader(xml));
161 
162         return toString(doc, indent);
163     }
164 
165 }