001 /*
002 * Copyright 2007 - 2007 JEuclid, http://jeuclid.sf.net
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017 /* $Id: MathMLSerializer.java,v 2bab6eb875e8 2010/08/11 16:45:50 max $ */
018
019 package net.sourceforge.jeuclid;
020
021 import java.io.StringWriter;
022
023 import javax.annotation.concurrent.ThreadSafe;
024 import javax.xml.transform.OutputKeys;
025 import javax.xml.transform.Transformer;
026 import javax.xml.transform.TransformerException;
027 import javax.xml.transform.TransformerFactory;
028 import javax.xml.transform.dom.DOMSource;
029 import javax.xml.transform.stream.StreamResult;
030
031 import org.apache.commons.logging.Log;
032 import org.apache.commons.logging.LogFactory;
033 import org.w3c.dom.Node;
034
035 /**
036 * Utility class to serialize DOM documents back into Strings.
037 * <p>
038 * This class can be used to generate String representations for an existing DOM
039 * Tree. The functionality is not restricted to JEuclid, and can be used for
040 * other DOM trees as well. In this case, you should set the addDoctype
041 * parameter to false.
042 *
043 * @version $Revision: 2bab6eb875e8 $
044 */
045 @ThreadSafe
046 public final class MathMLSerializer {
047
048 /**
049 * Logger for this class
050 */
051 private static final Log LOGGER = LogFactory.getLog(MathMLSerializer.class);
052
053 private MathMLSerializer() {
054 // empty on purpose
055 }
056
057 /**
058 * Serialize a document back into a String.
059 *
060 * @param doc
061 * a DOM model of a document, or a node in a document
062 * @param addDoctype
063 * if true, extra attributes such as docType will be set. This
064 * ensures maximum MathML compatibility. Use only with MathML DOM
065 * trees.
066 * @param format
067 * if true, result will be nicely formatted.
068 * @return the document serialized to a string
069 * @see #serializeDocument(Node, boolean, boolean, boolean)
070 */
071 public static String serializeDocument(final Node doc,
072 final boolean addDoctype, final boolean format) {
073 return MathMLSerializer.serializeDocument(doc, addDoctype, format,
074 false);
075 }
076
077 /**
078 * Serialize a document back into a String.
079 *
080 * @param doc
081 * a DOM model of a document.
082 * @param addDoctype
083 * if true, extra attributes such as docType will be set. This
084 * ensures maximum MathML compatibility. Use only with MathML DOM
085 * trees.
086 * @param format
087 * if true, result will be nicely formatted.
088 * @param omitXMLDecl
089 * if true, there will be no XML declaration.
090 * @return the document serialized to a string
091 */
092 public static String serializeDocument(final Node doc,
093 final boolean addDoctype, final boolean format,
094 final boolean omitXMLDecl) {
095 final StringWriter writer = new StringWriter();
096 try {
097 final Transformer transformer = TransformerFactory.newInstance()
098 .newTransformer();
099 final DOMSource source = new DOMSource(doc);
100 final StreamResult result = new StreamResult(writer);
101
102 if (addDoctype) {
103 transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC,
104 ResourceEntityResolver.MML2_PUBLICID);
105 transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM,
106 ResourceEntityResolver.MML2_SYSTEMID);
107 transformer.setOutputProperty(OutputKeys.MEDIA_TYPE,
108 Constants.MATHML_MIMETYPE);
109 }
110 MathMLSerializer.boolToProperty(format, OutputKeys.INDENT,
111 transformer);
112 MathMLSerializer.boolToProperty(omitXMLDecl,
113 OutputKeys.OMIT_XML_DECLARATION, transformer);
114 transformer.transform(source, result);
115 } catch (final TransformerException e) {
116 MathMLSerializer.LOGGER.warn(e.getMessage(), e);
117 }
118 return writer.toString();
119
120 }
121
122 private static void boolToProperty(final boolean bool, final String key,
123 final Transformer transformer) {
124 if (bool) {
125 transformer.setOutputProperty(key, "yes");
126 } else {
127 transformer.setOutputProperty(key, "no");
128 }
129 }
130
131 }