All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scala.xml.include.sax.XIncluder.scala Maven / Gradle / Ivy

/*                     __                                               *\
**     ________ ___   / /  ___     Scala API                            **
**    / __/ __// _ | / /  / _ |    (c) 2002-2010, LAMP/EPFL             **
**  __\ \/ /__/ __ |/ /__/ __ |    http://scala-lang.org/               **
** /____/\___/_/ |_/____/_/ | |                                         **
**                          |/                                          **
\*                                                                      */


package scala.xml
package include.sax

import scala.xml.include._
import collection.mutable.Stack

import org.xml.sax.{ ContentHandler, XMLReader, Locator, Attributes }
import org.xml.sax.ext.LexicalHandler
import java.io.{ File, OutputStream, OutputStreamWriter, Writer, IOException }

/** XIncluder is a SAX ContentHandler 
 * that writes its XML document onto an output stream after resolving
 * all xinclude:include elements.
 *
 * 

* based on Eliotte Rusty Harold's SAXXIncluder *

*/ class XIncluder(outs: OutputStream, encoding: String) extends ContentHandler with LexicalHandler { var out = new OutputStreamWriter(outs, encoding) def setDocumentLocator(locator: Locator) {} def startDocument() { try { out.write("\r\n"); } catch { case e:IOException => throw new SAXException("Write failed", e) } } def endDocument() { try { out.flush() } catch { case e:IOException => throw new SAXException("Flush failed", e) } } def startPrefixMapping(prefix: String , uri: String) {} def endPrefixMapping(prefix: String) {} def startElement(namespaceURI: String, localName: String, qualifiedName: String, atts: Attributes) = { try { out.write("<" + qualifiedName); var i = 0; while (i < atts.getLength()) { out.write(" "); out.write(atts.getQName(i)); out.write("='"); val value = atts.getValue(i); // @todo Need to use character references if the encoding // can't support the character out.write(xml.Utility.escape(value)) out.write("'"); i += 1 } out.write(">") } catch { case e:IOException => throw new SAXException("Write failed", e) } } def endElement(namespaceURI: String, localName:String, qualifiedName: String) { try { out.write("") } catch { case e: IOException => throw new SAXException("Write failed", e) } } // need to escape characters that are not in the given // encoding using character references???? def characters(ch: Array[Char], start: Int, length: Int) { try { var i = 0; while (i < length) { val c = ch(start+i); if (c == '&') out.write("&"); else if (c == '<') out.write("<"); // This next fix is normally not necessary. // However, it is required if text contains ]]> // (The end CDATA section delimiter) else if (c == '>') out.write(">"); else out.write(c); i = i+1; } } catch { case e: IOException => throw new SAXException("Write failed", e); } } def ignorableWhitespace(ch: Array[Char], start: Int , length: Int) { this.characters(ch, start, length) } // do I need to escape text in PI???? def processingInstruction(target: String, data: String) { try { out.write("") } catch { case e:IOException => throw new SAXException("Write failed", e) } } def skippedEntity(name: String) { try { out.write("&" + name + ";") } catch { case e:IOException => throw new SAXException("Write failed", e) } } // LexicalHandler methods private var inDTD: Boolean = false private val entities = new Stack[String]() def startDTD(name: String, publicID: String, systemID: String) { inDTD = true // if this is the source document, output a DOCTYPE declaration if (entities.isEmpty) { var id = "" if (publicID != null) id = " PUBLIC \"" + publicID + "\" \"" + systemID + '"'; else if (systemID != null) id = " SYSTEM \"" + systemID + '"'; try { out.write("\r\n") } catch { case e:IOException => throw new SAXException("Error while writing DOCTYPE", e) } } } def endDTD() {} def startEntity(name: String) { entities push name } def endEntity(name: String) { entities.pop() } def startCDATA() {} def endCDATA() {} // Just need this reference so we can ask if a comment is // inside an include element or not private var filter: XIncludeFilter = null def setFilter(filter: XIncludeFilter) { this.filter = filter } def comment(ch: Array[Char], start: Int, length: Int) { if (!inDTD && !filter.insideIncludeElement()) { try { out.write("") } catch { case e: IOException => throw new SAXException("Write failed", e) } } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy