KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > opencms > util > CmsXsltUtil


1 /*
2  * File : $Source: /usr/local/cvs/opencms/src/org/opencms/util/CmsXsltUtil.java,v $
3  * Date : $Date: 2006/03/31 15:25:39 $
4  * Version: $Revision: 1.2 $
5  *
6  * This library is part of OpenCms -
7  * the Open Source Content Mananagement System
8  *
9  * Copyright (C) 2005 Alkacon Software GmbH (http://www.alkacon.com)
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * Lesser General Public License for more details.
20  *
21  * For further information about Alkacon Software GmbH, please see the
22  * company website: http://www.alkacon.com
23  *
24  * For further information about OpenCms, please see the
25  * project website: http://www.opencms.org
26  *
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30  */

31
32 package org.opencms.util;
33
34 import org.opencms.file.CmsObject;
35 import org.opencms.main.CmsException;
36 import org.opencms.xml.CmsXmlException;
37
38 import java.io.BufferedReader JavaDoc;
39 import java.io.IOException JavaDoc;
40 import java.io.StringReader JavaDoc;
41 import java.io.StringWriter JavaDoc;
42 import java.util.StringTokenizer JavaDoc;
43
44 import javax.xml.transform.Source JavaDoc;
45 import javax.xml.transform.Transformer JavaDoc;
46 import javax.xml.transform.TransformerFactory JavaDoc;
47 import javax.xml.transform.stream.StreamResult JavaDoc;
48 import javax.xml.transform.stream.StreamSource JavaDoc;
49
50 /**
51  *
52  */

53 public class CmsXsltUtil {
54
55     /** The delimiter to separate the text. */
56     public static final char TEXT_DELIMITER = '"';
57
58     /** The delimiter to start a tag */
59     public static final String JavaDoc TAG_START_DELIMITER = "<";
60
61     /** The delimiter to end a tag */
62     public static final String JavaDoc TAG_END_DELIMITER = ">";
63
64     /** the delimiters, the csv data can be separated with.*/
65     static final String JavaDoc[] DELIMITERS = {";", ",", "\t"};
66     
67     /**
68      * Applies a XSLT Transformation to the content.<p>
69      *
70      * The method does not use DOM4J, because iso-8859-1 code ist not transformed correctly.
71      *
72      * @param cms the cms object
73      * @param xsltFile the XSLT transformation file
74      * @param xmlContent the XML content to transform
75      *
76      * @return the transformed xml
77      *
78      * @throws CmsXmlException if something goes wrong
79      * @throws CmsException if something goes wrong
80      */

81     public static String JavaDoc transformXmlContent(CmsObject cms, String JavaDoc xsltFile, String JavaDoc xmlContent) throws CmsException, CmsXmlException {
82
83         // JAXP reads data
84
Source JavaDoc xmlSource = new StreamSource JavaDoc(new StringReader JavaDoc(xmlContent));
85         String JavaDoc xsltString = new String JavaDoc(cms.readFile(xsltFile).getContents());
86         Source JavaDoc xsltSource = new StreamSource JavaDoc(new StringReader JavaDoc(xsltString));
87         String JavaDoc result = null;
88         
89         try {
90             TransformerFactory JavaDoc transFact = TransformerFactory.newInstance();
91             Transformer JavaDoc trans = transFact.newTransformer(xsltSource);
92     
93             StringWriter JavaDoc writer = new StringWriter JavaDoc();
94             trans.transform(xmlSource, new StreamResult JavaDoc(writer));
95             result = writer.toString();
96         } catch (Exception JavaDoc exc) {
97             throw new CmsXmlException(Messages.get().container(Messages.ERR_CSV_XML_TRANSFORMATION_FAILED_0));
98         }
99         
100         // cut of the prefacing declaration '<?xml version="1.0" encoding="UTF-8"?>'
101
if (result.startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")) {
102             return result.substring(38);
103         } else {
104             return result;
105         }
106     }
107
108     /**
109      * Changes content from csv to xml/html.<p>
110      *
111      * The method does not use DOM4J, because iso-8859-1 code ist not transformed correctly.
112      *
113      * @param cms the cms object
114      * @param xsltFile the XSLT transformation file
115      * @param csvContent the csv content to transform
116      * @param delimiter delimiter used to separate csv fields
117      *
118      * @return the transformed xml
119      *
120      * @throws CmsXmlException if something goes wrong
121      * @throws CmsException if something goes wrong
122      */

123     public static String JavaDoc transformCsvContent(CmsObject cms, String JavaDoc xsltFile, String JavaDoc csvContent, String JavaDoc delimiter) throws CmsException, CmsXmlException {
124
125         String JavaDoc xmlContent = "";
126         try {
127             xmlContent = getTableHtml(csvContent, delimiter);
128         } catch (IOException JavaDoc e) {
129             throw new CmsXmlException(Messages.get().container(Messages.ERR_CSV_XML_TRANSFORMATION_FAILED_0));
130         }
131
132         // if xslt file parameter is set, transform the raw html and set the css stylesheet property
133
// of the converted file to that of the stylesheet
134
if (xsltFile != null) {
135             xmlContent = transformXmlContent(cms, xsltFile, xmlContent);
136         }
137         
138         return xmlContent;
139     }
140
141     /**
142      * Converts CSV data to xml.<p>
143      *
144      * @return a XML representation of the csv data
145      *
146      * @param csvData the csv data to convert
147      * @param colGroup the format definitions for the table columns, can be null
148      * @param delimiter the delimiter to separate the values with
149      *
150      * @throws IOException if there is an IO problem
151      */

152     private static String JavaDoc getTableHtml(String JavaDoc csvData, String JavaDoc delimiter) throws IOException JavaDoc {
153
154         String JavaDoc lineSeparator = System.getProperty("line.separator");
155         String JavaDoc formatString = csvData.substring(0, csvData.indexOf(lineSeparator));
156
157         if (delimiter == null) {
158             delimiter = getPreferredDelimiter(csvData);
159         }
160         
161         StringBuffer JavaDoc xml = new StringBuffer JavaDoc("<table>");
162         if (isFormattingInformation(formatString, delimiter)) {
163             // transform formatting to HTML colgroup
164
xml.append(getColGroup(formatString, delimiter));
165             // cut of first line
166
csvData = csvData.substring(formatString.length() + lineSeparator.length());
167         }
168
169         String JavaDoc line;
170         BufferedReader JavaDoc br = new BufferedReader JavaDoc(new StringReader JavaDoc(csvData));
171         while ((line = br.readLine()) != null) {
172             xml.append("<tr>\n");
173
174             // must use tokenizer with delimiters include in order to handle empty cells appropriately
175
StringTokenizer JavaDoc t = new StringTokenizer JavaDoc(line, delimiter, true);
176             boolean hasValue = false;
177             while (t.hasMoreElements()) {
178                 String JavaDoc item = (String JavaDoc)t.nextElement();
179                 if (!hasValue) {
180                     xml.append("\t<td>");
181                     hasValue = true;
182                 }
183                 if (!item.equals(delimiter)) {
184
185                     // remove enclosing delimiters
186
item = removeStringDelimiters(item);
187
188                     // in order to allow links, lines starting and ending with tag delimiters (< ...>) remains unescaped
189
if (item.startsWith(TAG_START_DELIMITER) && item.endsWith(TAG_END_DELIMITER)) {
190                         xml.append(item);
191                     } else {
192                         xml.append(CmsStringUtil.escapeHtml(item));
193                     }
194                 } else {
195                     xml.append("</td>\n");
196                     hasValue = false;
197                 }
198             }
199             if (hasValue) {
200                 xml.append("</td>\n");
201             } else {
202                 xml.append("<td></td>\n");
203             }
204
205             xml.append("</tr>\n");
206         }
207
208         return xml.append("</table>").toString();
209     }
210
211     /**
212      * Converts a delimiter separated format string int o colgroup html fragment.<p>
213      * @param formatString the formatstring to convert
214      * @param delimiter the delimiter the formats (l,r or c) are delimited with
215      *
216      * @return the resulting colgroup HTML
217      */

218     private static String JavaDoc getColGroup(String JavaDoc formatString, String JavaDoc delimiter) {
219
220         StringBuffer JavaDoc colgroup = new StringBuffer JavaDoc(128);
221         String JavaDoc[] formatStrings = formatString.split(delimiter);
222         colgroup.append("<colgroup>");
223         for (int i = 0; i < formatStrings.length; i++) {
224             colgroup.append("<col align=\"");
225             char align = formatStrings[i].trim().charAt(0);
226             switch (align) {
227                 case 'l':
228                     colgroup.append("left");
229                     break;
230                 case 'c':
231                     colgroup.append("center");
232                     break;
233                 case 'r':
234                     colgroup.append("right");
235                     break;
236                 default:
237                     throw new RuntimeException JavaDoc("invalid format option");
238             }
239             colgroup.append("\"/>");
240         }
241         return colgroup.append("</colgroup>").toString();
242     }
243
244     /**
245      * Tests if the given string is a <code>delimiter</code> separated list of Formatting Information.<p>
246      *
247      * @param formatString the string to check
248      * @param delimiter the list separators
249      *
250      * @return true if the string is a <code>delimiter</code> separated list of Formatting Information
251      */

252     private static boolean isFormattingInformation(String JavaDoc formatString, String JavaDoc delimiter) {
253
254         String JavaDoc[] formatStrings = formatString.split(delimiter);
255         for (int i = 0; i < formatStrings.length; i++) {
256             if (!formatStrings[i].trim().matches("[lcr]")) {
257                 return false;
258             }
259         }
260         return true;
261     }
262
263     /**
264      * Removes the string delimiters from a key (as well as any white space
265      * outside the delimiters).<p>
266      *
267      * @param key the key (including delimiters)
268      *
269      * @return the key without delimiters
270      */

271     private static String JavaDoc removeStringDelimiters(String JavaDoc key) {
272
273         String JavaDoc k = key.trim();
274         if (CmsStringUtil.isNotEmpty(k)) {
275             if (k.charAt(0) == TEXT_DELIMITER) {
276                 k = k.substring(1);
277             }
278             if (k.charAt(k.length() - 1) == TEXT_DELIMITER) {
279                 k = k.substring(0, k.length() - 1);
280             }
281         }
282         // replace excel protected quotations marks ("") by single quotation marks
283
k = CmsStringUtil.substitute(k, "\"\"", "\"");
284         return k;
285     }
286     
287     /**
288      * returns the Delimiter that most often occures in the CSV content.<p>
289      *
290      * @param csvData the comma separated values
291      *
292      * @return the delimiter, that is best applicable for the csvData
293      */

294     private static String JavaDoc getPreferredDelimiter(String JavaDoc csvData) {
295
296         String JavaDoc bestMatch = "";
297         int bestMatchCount = 0;
298         // find for each delimiter, how often it occures in the String csvData
299
for (int i = 0; i < DELIMITERS.length; i++) {
300             int currentCount = csvData.split(DELIMITERS[i]).length;
301             if (currentCount > bestMatchCount) {
302                 bestMatch = DELIMITERS[i];
303                 bestMatchCount = currentCount;
304             }
305         }
306         return bestMatch;
307     }
308 }
309
Popular Tags