1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   *
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         if (content.startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")) {
147             content = StringUtil.replaceFirst(
148                 content, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>",
149                 "<?xml version=\"1.0\"?>");
150         }
151 
152         return content;
153     }
154 
155     public static String toString(String xml)
156         throws DocumentException, IOException {
157 
158         return toString(xml, StringPool.TAB);
159     }
160 
161     public static String toString(String xml, String indent)
162         throws DocumentException, IOException {
163 
164         SAXReader saxReader = new SAXReader();
165 
166         Document document = saxReader.read(new UnsyncStringReader(xml));
167 
168         return toString(document, indent);
169     }
170 
171 }