001: /*
002: * The Apache Software License, Version 1.1
003: *
004: *
005: * Copyright (c) 1999 The Apache Software Foundation. All rights
006: * reserved.
007: *
008: * Redistribution and use in source and binary forms, with or without
009: * modification, are permitted provided that the following conditions
010: * are met:
011: *
012: * 1. Redistributions of source code must retain the above copyright
013: * notice, this list of conditions and the following disclaimer.
014: *
015: * 2. Redistributions in binary form must reproduce the above copyright
016: * notice, this list of conditions and the following disclaimer in
017: * the documentation and/or other materials provided with the
018: * distribution.
019: *
020: * 3. The end-user documentation included with the redistribution,
021: * if any, must include the following acknowledgment:
022: * "This product includes software developed by the
023: * Apache Software Foundation (http://www.apache.org/)."
024: * Alternately, this acknowledgment may appear in the software itself,
025: * if and wherever such third-party acknowledgments normally appear.
026: *
027: * 4. The names "Xerces" and "Apache Software Foundation" must
028: * not be used to endorse or promote products derived from this
029: * software without prior written permission. For written
030: * permission, please contact apache@apache.org.
031: *
032: * 5. Products derived from this software may not be called "Apache",
033: * nor may "Apache" appear in their name, without prior written
034: * permission of the Apache Software Foundation.
035: *
036: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
037: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
038: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
039: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
040: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
041: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
042: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
043: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
044: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
045: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
046: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
047: * SUCH DAMAGE.
048: * ====================================================================
049: *
050: * This software consists of voluntary contributions made by many
051: * individuals on behalf of the Apache Software Foundation and was
052: * originally based on software copyright (c) 1999, International
053: * Business Machines, Inc., http://www.apache.org. For more
054: * information on the Apache Software Foundation, please see
055: * <http://www.apache.org/>.
056: */
057:
058: // Aug 21, 2000:
059: // Added ability to omit DOCTYPE declaration.
060: // Reported by Lars Martin <lars@smb-tec.com>
061: // Aug 25, 2000:
062: // Added ability to omit comments.
063: // Contributed by Anupam Bagchi <abagchi@jtcsv.com>
064:
065: package org.apache.xml.serialize;
066:
067: import java.util.Hashtable;
068:
069: import org.w3c.dom.Document;
070: import org.w3c.dom.DocumentType;
071: import org.w3c.dom.Node;
072: import org.w3c.dom.html.HTMLDocument;
073:
074: /**
075: * Specifies an output format to control the serializer. Based on the
076: * XSLT specification for output format, plus additional parameters.
077: * Used to select the suitable serializer and determine how the
078: * document should be formatted on output.
079: * <p>
080: * The two interesting constructors are:
081: * <ul>
082: * <li>{@link #OutputFormat(String,String,boolean)} creates a format
083: * for the specified method (XML, HTML, Text, etc), encoding and indentation
084: * <li>{@link #OutputFormat(Document,String,boolean)} creates a format
085: * compatible with the document type (XML, HTML, Text, etc), encoding and
086: * indentation
087: * </ul>
088: *
089: *
090: * @version $Revision: 1.11.2.1 $ $Date: 2001/11/07 19:00:34 $
091: * @author <a href="mailto:arkin@intalio.com">Assaf Arkin</a>
092: * <a href="mailto:visco@intalio.com">Keith Visco</a>
093: * @see Serializer
094: * @see Method
095: * @see LineSeparator
096: */
097: public class OutputFormat {
098:
099: public static class DTD {
100:
101: /**
102: * Public identifier for HTML document type.
103: */
104: public static final String HTMLPublicId = "-//W3C//DTD HTML 4.0//EN";
105:
106: /**
107: * System identifier for HTML document type.
108: */
109: public static final String HTMLSystemId = "http://www.w3.org/TR/WD-html-in-xml/DTD/xhtml1-strict.dtd";
110:
111: /**
112: * Public identifier for XHTML document type.
113: */
114: public static final String XHTMLPublicId = "-//W3C//DTD XHTML 1.0 Strict//EN";
115:
116: /**
117: * System identifier for XHTML document type.
118: */
119: public static final String XHTMLSystemId = "http://www.w3.org/TR/WD-html-in-xml/DTD/xhtml1-strict.dtd";
120:
121: }
122:
123: public static class Defaults {
124:
125: /**
126: * If indentation is turned on, the default identation
127: * level is 4.
128: *
129: * @see #setIndenting(boolean)
130: */
131: public static final int Indent = 4;
132:
133: /**
134: * The default encoding for Web documents it UTF-8.
135: *
136: * @see #getEncoding()
137: */
138: public static final String Encoding = "UTF-8";
139:
140: /**
141: * The default line width at which to break long lines
142: * when identing. This is set to 72.
143: */
144: public static final int LineWidth = 72;
145:
146: }
147:
148: /**
149: * Holds the output method specified for this document,
150: * or null if no method was specified.
151: */
152: private String _method;
153:
154: /**
155: * Specifies the version of the output method.
156: */
157: private String _version;
158:
159: /**
160: * The indentation level, or zero if no indentation
161: * was requested.
162: */
163: private int _indent = 0;
164:
165: /**
166: * The encoding to use, if an input stream is used.
167: * The default is always UTF-8.
168: */
169: private String _encoding = Defaults.Encoding;
170:
171: /**
172: * The EncodingInfo instance for _encoding.
173: */
174: private EncodingInfo _encodingInfo = null;
175:
176: /**
177: * The specified media type or null.
178: */
179: private String _mediaType;
180:
181: /**
182: * The specified document type system identifier, or null.
183: */
184: private String _doctypeSystem;
185:
186: /**
187: * The specified document type public identifier, or null.
188: */
189: private String _doctypePublic;
190:
191: /**
192: * Ture if the XML declaration should be ommited;
193: */
194: private boolean _omitXmlDeclaration = false;
195:
196: /**
197: * Ture if the DOCTYPE declaration should be ommited;
198: */
199: private boolean _omitDoctype = false;
200:
201: /**
202: * Ture if comments should be ommited;
203: */
204: private boolean _omitComments = false;
205:
206: /**
207: * Ture if the comments should be ommited;
208: */
209: private boolean _stripComments = false;
210:
211: /**
212: * True if the document type should be marked as standalone.
213: */
214: private boolean _standalone = false;
215:
216: /**
217: * List of element tag names whose text node children must
218: * be output as CDATA.
219: */
220: private String[] _cdataElements;
221:
222: /**
223: * List of element tag names whose text node children must
224: * be output unescaped.
225: */
226: private String[] _nonEscapingElements;
227:
228: /**
229: * The selected line separator.
230: */
231: private String _lineSeparator = LineSeparator.Web;
232:
233: /**
234: * The line width at which to wrap long lines when indenting.
235: */
236: private int _lineWidth = Defaults.LineWidth;
237:
238: /**
239: * True if spaces should be preserved in elements that do not
240: * specify otherwise, or specify the default behavior.
241: */
242: private boolean _preserve = false;
243: /** If true, an empty string valued attribute is output as "". If false and
244: * and we are using the HTMLSerializer, then only the attribute name is
245: * serialized. Defaults to false for backwards compatibility.
246: */
247: private boolean _preserveEmptyAttributes = false;
248:
249: /**
250: * Constructs a new output format with the default values.
251: */
252: public OutputFormat() {
253: }
254:
255: /**
256: * Constructs a new output format with the default values for
257: * the specified method and encoding. If <tt>indent</tt>
258: * is true, the document will be pretty printed with the default
259: * indentation level and default line wrapping.
260: *
261: * @param method The specified output method
262: * @param encoding The specified encoding
263: * @param indenting True for pretty printing
264: * @see #setEncoding
265: * @see #setIndenting
266: * @see #setMethod
267: */
268: public OutputFormat(String method, String encoding,
269: boolean indenting) {
270: setMethod(method);
271: setEncoding(encoding);
272: setIndenting(indenting);
273: }
274:
275: /**
276: * Constructs a new output format with the proper method,
277: * document type identifiers and media type for the specified
278: * document.
279: *
280: * @param doc The document to output
281: * @see #whichMethod
282: */
283: public OutputFormat(Document doc) {
284: setMethod(whichMethod(doc));
285: setDoctype(whichDoctypePublic(doc), whichDoctypeSystem(doc));
286: setMediaType(whichMediaType(getMethod()));
287: }
288:
289: /**
290: * Constructs a new output format with the proper method,
291: * document type identifiers and media type for the specified
292: * document, and with the specified encoding. If <tt>indent</tt>
293: * is true, the document will be pretty printed with the default
294: * indentation level and default line wrapping.
295: *
296: * @param doc The document to output
297: * @param encoding The specified encoding
298: * @param indenting True for pretty printing
299: * @see #setEncoding
300: * @see #setIndenting
301: * @see #whichMethod
302: */
303: public OutputFormat(Document doc, String encoding, boolean indenting) {
304: this (doc);
305: setEncoding(encoding);
306: setIndenting(indenting);
307: }
308:
309: /**
310: * Returns the method specified for this output format.
311: * Typically the method will be <tt>xml</tt>, <tt>html</tt>
312: * or <tt>text</tt>, but it might be other values.
313: * If no method was specified, null will be returned
314: * and the most suitable method will be determined for
315: * the document by calling {@link #whichMethod}.
316: *
317: * @return The specified output method, or null
318: */
319: public String getMethod() {
320: return _method;
321: }
322:
323: /**
324: * Sets the method for this output format.
325: *
326: * @see #getMethod
327: * @param method The output method, or null
328: */
329: public void setMethod(String method) {
330: _method = method;
331: }
332:
333: /**
334: * Returns the version for this output method.
335: * If no version was specified, will return null
336: * and the default version number will be used.
337: * If the serializerr does not support that particular
338: * version, it should default to a supported version.
339: *
340: * @return The specified method version, or null
341: */
342: public String getVersion() {
343: return _version;
344: }
345:
346: /**
347: * Sets the version for this output method.
348: * For XML the value would be "1.0", for HTML
349: * it would be "4.0".
350: *
351: * @see #getVersion
352: * @param version The output method version, or null
353: */
354: public void setVersion(String version) {
355: _version = version;
356: }
357:
358: /**
359: * Returns the indentation specified. If no indentation
360: * was specified, zero is returned and the document
361: * should not be indented.
362: *
363: * @return The indentation or zero
364: * @see #setIndenting
365: */
366: public int getIndent() {
367: return _indent;
368: }
369:
370: /**
371: * Returns true if indentation was specified.
372: */
373: public boolean getIndenting() {
374: return (_indent > 0);
375: }
376:
377: /**
378: * Sets the indentation. The document will not be
379: * indented if the indentation is set to zero.
380: * Calling {@link #setIndenting} will reset this
381: * value to zero (off) or the default (on).
382: *
383: * @param indent The indentation, or zero
384: */
385: public void setIndent(int indent) {
386: if (indent < 0)
387: _indent = 0;
388: else
389: _indent = indent;
390: }
391:
392: /**
393: * Sets the indentation on and off. When set on, the default
394: * indentation level and default line wrapping is used
395: * (see {@link #DEFAULT_INDENT} and {@link #DEFAULT_LINE_WIDTH}).
396: * To specify a different indentation level or line wrapping,
397: * use {@link #setIndent} and {@link #setLineWidth}.
398: *
399: * @param on True if indentation should be on
400: */
401: public void setIndenting(boolean on) {
402: if (on) {
403: _indent = Defaults.Indent;
404: _lineWidth = Defaults.LineWidth;
405: } else {
406: _indent = 0;
407: _lineWidth = 0;
408: }
409: }
410:
411: /**
412: * Returns the specified encoding. If no encoding was
413: * specified, the default is always "UTF-8".
414: *
415: * @return The encoding
416: */
417: public String getEncoding() {
418: return _encoding;
419: }
420:
421: /**
422: * Sets the encoding for this output method. If no
423: * encoding was specified, the default is always "UTF-8".
424: * Make sure the encoding is compatible with the one
425: * used by the {@link java.io.Writer}.
426: *
427: * @see #getEncoding
428: * @param encoding The encoding, or null
429: */
430: public void setEncoding(String encoding) {
431: _encoding = encoding;
432: _encodingInfo = null;
433: }
434:
435: /**
436: * Sets the encoding for this output method with an <code>EncodingInfo</code>
437: * instance.
438: */
439: public void setEncoding(EncodingInfo encInfo) {
440: _encoding = encInfo.getName();
441: _encodingInfo = encInfo;
442: }
443:
444: /**
445: * Returns an <code>EncodingInfo<code> instance for the encoding.
446: *
447: * @see setEncoding
448: */
449: public EncodingInfo getEncodingInfo() {
450: if (_encodingInfo == null)
451: _encodingInfo = Encodings.getEncodingInfo(_encoding);
452: return _encodingInfo;
453: }
454:
455: /**
456: * Returns the specified media type, or null.
457: * To determine the media type based on the
458: * document type, use {@link #whichMediaType}.
459: *
460: * @return The specified media type, or null
461: */
462: public String getMediaType() {
463: return _mediaType;
464: }
465:
466: /**
467: * Sets the media type.
468: *
469: * @see #getMediaType
470: * @param mediaType The specified media type
471: */
472: public void setMediaType(String mediaType) {
473: _mediaType = mediaType;
474: }
475:
476: /**
477: * Sets the document type public and system identifiers.
478: * Required only if the DOM Document or SAX events do not
479: * specify the document type, and one must be present in
480: * the serialized document. Any document type specified
481: * by the DOM Document or SAX events will override these
482: * values.
483: *
484: * @param publicId The public identifier, or null
485: * @param systemId The system identifier, or null
486: */
487: public void setDoctype(String publicId, String systemId) {
488: _doctypePublic = publicId;
489: _doctypeSystem = systemId;
490: }
491:
492: /**
493: * Returns the specified document type public identifier,
494: * or null.
495: */
496: public String getDoctypePublic() {
497: return _doctypePublic;
498: }
499:
500: /**
501: * Returns the specified document type system identifier,
502: * or null.
503: */
504: public String getDoctypeSystem() {
505: return _doctypeSystem;
506: }
507:
508: /**
509: * Returns true if comments should be ommited.
510: * The default is false.
511: */
512: public boolean getOmitComments() {
513: return _omitComments;
514: }
515:
516: /**
517: * Sets comment omitting on and off.
518: *
519: * @param omit True if comments should be ommited
520: */
521: public void setOmitComments(boolean omit) {
522: _omitComments = omit;
523: }
524:
525: /**
526: * Returns true if the DOCTYPE declaration should
527: * be ommited. The default is false.
528: */
529: public boolean getOmitDocumentType() {
530: return _omitDoctype;
531: }
532:
533: /**
534: * Sets DOCTYPE declaration omitting on and off.
535: *
536: * @param omit True if DOCTYPE declaration should be ommited
537: */
538: public void setOmitDocumentType(boolean omit) {
539: _omitDoctype = omit;
540: }
541:
542: /**
543: * Returns true if the XML document declaration should
544: * be ommited. The default is false.
545: */
546: public boolean getOmitXMLDeclaration() {
547: return _omitXmlDeclaration;
548: }
549:
550: /**
551: * Sets XML declaration omitting on and off.
552: *
553: * @param omit True if XML declaration should be ommited
554: */
555: public void setOmitXMLDeclaration(boolean omit) {
556: _omitXmlDeclaration = omit;
557: }
558:
559: /**
560: * Returns true if the document type is standalone.
561: * The default is false.
562: */
563: public boolean getStandalone() {
564: return _standalone;
565: }
566:
567: /**
568: * Sets document DTD standalone. The public and system
569: * identifiers must be null for the document to be
570: * serialized as standalone.
571: *
572: * @param standalone True if document DTD is standalone
573: */
574: public void setStandalone(boolean standalone) {
575: _standalone = standalone;
576: }
577:
578: /**
579: * Returns a list of all the elements whose text node children
580: * should be output as CDATA, or null if no such elements were
581: * specified.
582: */
583: public String[] getCDataElements() {
584: return _cdataElements;
585: }
586:
587: /**
588: * Returns true if the text node children of the given elements
589: * should be output as CDATA.
590: *
591: * @param tagName The element's tag name
592: * @return True if should serialize as CDATA
593: */
594: public boolean isCDataElement(String tagName) {
595: int i;
596:
597: if (_cdataElements == null)
598: return false;
599: for (i = 0; i < _cdataElements.length; ++i)
600: if (_cdataElements[i].equals(tagName))
601: return true;
602: return false;
603: }
604:
605: /**
606: * Sets the list of elements for which text node children
607: * should be output as CDATA.
608: *
609: * @param cdataElements List of CDATA element tag names
610: */
611: public void setCDataElements(String[] cdataElements) {
612: _cdataElements = cdataElements;
613: }
614:
615: /**
616: * Returns a list of all the elements whose text node children
617: * should be output unescaped (no character references), or null
618: * if no such elements were specified.
619: */
620: public String[] getNonEscapingElements() {
621: return _nonEscapingElements;
622: }
623:
624: /**
625: * Returns true if the text node children of the given elements
626: * should be output unescaped.
627: *
628: * @param tagName The element's tag name
629: * @return True if should serialize unescaped
630: */
631: public boolean isNonEscapingElement(String tagName) {
632: int i;
633:
634: if (_nonEscapingElements == null)
635: return false;
636: for (i = 0; i < _nonEscapingElements.length; ++i)
637: if (_nonEscapingElements[i].equals(tagName))
638: return true;
639: return false;
640: }
641:
642: /**
643: * Sets the list of elements for which text node children
644: * should be output unescaped (no character references).
645: *
646: * @param nonEscapingElements List of unescaped element tag names
647: */
648: public void setNonEscapingElements(String[] nonEscapingElements) {
649: _nonEscapingElements = nonEscapingElements;
650: }
651:
652: /**
653: * Returns a specific line separator to use. The default is the
654: * Web line separator (<tt>\n</tt>). A string is returned to
655: * support double codes (CR + LF).
656: *
657: * @return The specified line separator
658: */
659: public String getLineSeparator() {
660: return _lineSeparator;
661: }
662:
663: /**
664: * Sets the line separator. The default is the Web line separator
665: * (<tt>\n</tt>). The machine's line separator can be obtained
666: * from the system property <tt>line.separator</tt>, but is only
667: * useful if the document is edited on machines of the same type.
668: * For general documents, use the Web line separator.
669: *
670: * @param lineSeparator The specified line separator
671: */
672: public void setLineSeparator(String lineSeparator) {
673: if (lineSeparator == null)
674: _lineSeparator = LineSeparator.Web;
675: else
676: _lineSeparator = lineSeparator;
677: }
678:
679: /**
680: * Returns true if the default behavior for this format is to
681: * preserve spaces. All elements that do not specify otherwise
682: * or specify the default behavior will be formatted based on
683: * this rule. All elements that specify space preserving will
684: * always preserve space.
685: */
686: public boolean getPreserveSpace() {
687: return _preserve;
688: }
689:
690: /**
691: * Sets space preserving as the default behavior. The default is
692: * space stripping and all elements that do not specify otherwise
693: * or use the default value will not preserve spaces.
694: *
695: * @param preserve True if spaces should be preserved
696: */
697: public void setPreserveSpace(boolean preserve) {
698: _preserve = preserve;
699: }
700:
701: /**
702: * Return the selected line width for breaking up long lines.
703: * When indenting, and only when indenting, long lines will be
704: * broken at space boundaries based on this line width.
705: * No line wrapping occurs if this value is zero.
706: */
707: public int getLineWidth() {
708: return _lineWidth;
709: }
710:
711: /**
712: * Sets the line width. If zero then no line wrapping will
713: * occur. Calling {@link #setIndenting} will reset this
714: * value to zero (off) or the default (on).
715: *
716: * @param lineWidth The line width to use, zero for default
717: * @see #getLineWidth
718: * @see #setIndenting
719: */
720: public void setLineWidth(int lineWidth) {
721: if (lineWidth <= 0)
722: _lineWidth = 0;
723: else
724: _lineWidth = lineWidth;
725: }
726:
727: /**
728: * Returns the preserveEmptyAttribute flag. If flag is false, then'
729: * attributes with empty string values are output as the attribute
730: * name only (in HTML mode).
731: * @return preserve the preserve flag
732: */
733: public boolean getPreserveEmptyAttributes() {
734: return _preserveEmptyAttributes;
735: }
736:
737: /**
738: * Sets the preserveEmptyAttribute flag. If flag is false, then'
739: * attributes with empty string values are output as the attribute
740: * name only (in HTML mode).
741: * @param preserve the preserve flag
742: */
743: public void setPreserveEmptyAttributes(boolean preserve) {
744: _preserveEmptyAttributes = preserve;
745: }
746:
747: /**
748: * Returns the last printable character based on the selected
749: * encoding. Control characters and non-printable characters
750: * are always printed as character references.
751: */
752: public char getLastPrintable() {
753: if (getEncoding() != null
754: && (getEncoding().equalsIgnoreCase("ASCII")))
755: return 0xFF;
756: else
757: return 0xFFFF;
758: }
759:
760: /**
761: * Determine the output method for the specified document.
762: * If the document is an instance of {@link org.w3c.dom.html.HTMLDocument}
763: * then the method is said to be <tt>html</tt>. If the root
764: * element is 'html' and all text nodes preceding the root
765: * element are all whitespace, then the method is said to be
766: * <tt>html</tt>. Otherwise the method is <tt>xml</tt>.
767: *
768: * @param doc The document to check
769: * @return The suitable method
770: */
771: public static String whichMethod(Document doc) {
772: Node node;
773: String value;
774: int i;
775:
776: // If document is derived from HTMLDocument then the default
777: // method is html.
778: if (doc instanceof HTMLDocument)
779: return Method.HTML;
780:
781: // Lookup the root element and the text nodes preceding it.
782: // If root element is html and all text nodes contain whitespace
783: // only, the method is html.
784:
785: // FIXME (SM) should we care about namespaces here?
786:
787: node = doc.getFirstChild();
788: while (node != null) {
789: // If the root element is html, the method is html.
790: if (node.getNodeType() == Node.ELEMENT_NODE) {
791: if (node.getNodeName().equalsIgnoreCase("html")) {
792: return Method.HTML;
793: } else if (node.getNodeName().equalsIgnoreCase("root")) {
794: return Method.FOP;
795: } else {
796: return Method.XML;
797: }
798: } else if (node.getNodeType() == Node.TEXT_NODE) {
799: // If a text node preceding the root element contains
800: // only whitespace, this might be html, otherwise it's
801: // definitely xml.
802: value = node.getNodeValue();
803: for (i = 0; i < value.length(); ++i)
804: if (value.charAt(i) != 0x20
805: && value.charAt(i) != 0x0A
806: && value.charAt(i) != 0x09
807: && value.charAt(i) != 0x0D)
808: return Method.XML;
809: }
810: node = node.getNextSibling();
811: }
812: // Anything else, the method is xml.
813: return Method.XML;
814: }
815:
816: /**
817: * Returns the document type public identifier
818: * specified for this document, or null.
819: */
820: public static String whichDoctypePublic(Document doc) {
821: DocumentType doctype;
822:
823: /* DOM Level 2 was introduced into the code base*/
824: doctype = doc.getDoctype();
825: if (doctype != null) {
826: // Note on catch: DOM Level 1 does not specify this method
827: // and the code will throw a NoSuchMethodError
828: try {
829: return doctype.getPublicId();
830: } catch (Error except) {
831: }
832: }
833:
834: if (doc instanceof HTMLDocument)
835: return DTD.XHTMLPublicId;
836: return null;
837: }
838:
839: /**
840: * Returns the document type system identifier
841: * specified for this document, or null.
842: */
843: public static String whichDoctypeSystem(Document doc) {
844: DocumentType doctype;
845:
846: /* DOM Level 2 was introduced into the code base*/
847: doctype = doc.getDoctype();
848: if (doctype != null) {
849: // Note on catch: DOM Level 1 does not specify this method
850: // and the code will throw a NoSuchMethodError
851: try {
852: return doctype.getSystemId();
853: } catch (Error except) {
854: }
855: }
856:
857: if (doc instanceof HTMLDocument)
858: return DTD.XHTMLSystemId;
859: return null;
860: }
861:
862: /**
863: * Returns the suitable media format for a document
864: * output with the specified method.
865: */
866: public static String whichMediaType(String method) {
867: if (method.equalsIgnoreCase(Method.XML))
868: return "text/xml";
869: if (method.equalsIgnoreCase(Method.HTML))
870: return "text/html";
871: if (method.equalsIgnoreCase(Method.XHTML))
872: return "text/html";
873: if (method.equalsIgnoreCase(Method.TEXT))
874: return "text/plain";
875: if (method.equalsIgnoreCase(Method.FOP))
876: return "application/pdf";
877: return null;
878: }
879:
880: }
|