diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/library/scala/runtime/compat/StringBuilder.scala | 10 | ||||
-rw-r--r-- | src/library/scala/xml/NamespaceBinding.scala | 30 | ||||
-rw-r--r-- | src/library/scala/xml/NodeTraverser.scala | 16 | ||||
-rw-r--r-- | src/library/scala/xml/PrettyPrinter.scala | 341 | ||||
-rw-r--r-- | src/library/scala/xml/parsing/ConstructingHandler.scala | 26 | ||||
-rw-r--r-- | src/library/scala/xml/parsing/ConstructingParser.scala | 29 | ||||
-rw-r--r-- | src/library/scala/xml/parsing/MarkupHandler.scala | 87 | ||||
-rw-r--r-- | src/library/scala/xml/parsing/MarkupParser.scala | 790 | ||||
-rw-r--r-- | src/library/scala/xml/transform/BasicTransformer.scala | 114 | ||||
-rw-r--r-- | src/library/scala/xml/transform/RewriteRule.scala | 15 |
10 files changed, 746 insertions, 712 deletions
diff --git a/src/library/scala/runtime/compat/StringBuilder.scala b/src/library/scala/runtime/compat/StringBuilder.scala index 4703698583..0d3e0da47d 100644 --- a/src/library/scala/runtime/compat/StringBuilder.scala +++ b/src/library/scala/runtime/compat/StringBuilder.scala @@ -9,26 +9,30 @@ // $Id$ -package scala.runtime.compat; - +package scala.runtime.compat class StringBuilder { val str = new StringBuffer() + def this(s: String) = { this(); str.append(s) } + def charAt(i: Int): Char = str.charAt(i) def append(x: Any): StringBuilder = { str.append(x) this } + def append(x: Char): StringBuilder = { str.append(x) - this; + this } + def append(x: String): StringBuilder = { str.append(x) this } + def length(): Int = str.length() def setLength(i: Int) = str.setLength(i) diff --git a/src/library/scala/xml/NamespaceBinding.scala b/src/library/scala/xml/NamespaceBinding.scala index f2a0c97f0a..ad1423216b 100644 --- a/src/library/scala/xml/NamespaceBinding.scala +++ b/src/library/scala/xml/NamespaceBinding.scala @@ -9,7 +9,7 @@ // $Id$ -package scala.xml; +package scala.xml import scala.runtime.compat.StringBuilder @@ -18,21 +18,21 @@ import scala.runtime.compat.StringBuilder * prefix. the absent namespace is represented with the null uri. Neither * prefix nor uri may be empty, which is not checked. * + * @author Burak Emir * @version 1.0 - * @author Burak Emir */ [serializable] class NamespaceBinding(val prefix: String, val uri: String, val parent: NamespaceBinding) extends AnyRef { - private val serialVersionUID = 0 - 2518644165573446725L; + private val serialVersionUID = 0 - 2518644165573446725L if (null != prefix && 0 == prefix.length()) - Predef.error("zero length prefix not allowed"); + Predef.error("zero length prefix not allowed") def getURI(_prefix: String): String = - if (prefix == _prefix) uri else parent.getURI(_prefix); + if (prefix == _prefix) uri else parent.getURI(_prefix) /** Returns some prefix that is mapped to the prefix. * @@ -40,23 +40,23 @@ class NamespaceBinding(val prefix: String, * @return */ def getPrefix(_uri: String): String = - if (_uri == uri) uri else parent.getURI(_uri); + if (_uri == uri) uri else parent.getURI(_uri) override def toString(): String = { - val sb = new StringBuilder(); - toString(sb, TopScope); - sb.toString(); + val sb = new StringBuilder() + toString(sb, TopScope) + sb.toString() } def toString(stop: NamespaceBinding): String = { - val sb = new StringBuilder(); - toString(sb, stop); - sb.toString(); + val sb = new StringBuilder() + toString(sb, stop) + sb.toString() } - def toString(sb:StringBuilder, stop:NamespaceBinding): Unit = { + def toString(sb: StringBuilder, stop: NamespaceBinding): Unit = { if (this ne stop) { // contains? - sb.append(" xmlns"); + sb.append(" xmlns") if (prefix != null) { sb.append(':').append(prefix) } @@ -64,7 +64,7 @@ class NamespaceBinding(val prefix: String, .append('"') .append(uri) .append('"'); - parent.toString(sb, stop); // copy(ignore) + parent.toString(sb, stop) // copy(ignore) } } diff --git a/src/library/scala/xml/NodeTraverser.scala b/src/library/scala/xml/NodeTraverser.scala index f3febb9e2a..f6fac46bb4 100644 --- a/src/library/scala/xml/NodeTraverser.scala +++ b/src/library/scala/xml/NodeTraverser.scala @@ -9,9 +9,13 @@ // $Id$ -package scala.xml; - +package scala.xml +/** This class ... + * + * @author Burak Emir + * @version 1.0 + */ abstract class NodeTraverser extends parsing.MarkupHandler { def traverse(n: Node): Unit = n match { @@ -20,11 +24,11 @@ abstract class NodeTraverser extends parsing.MarkupHandler { case x:Text => text(0, x.data) case x:EntityRef => entityRef(0, x.entityName) case _ => - elemStart(0, n.prefix, n.label, n.attributes, n.scope); + elemStart(0, n.prefix, n.label, n.attributes, n.scope) for (val m <- n.child) - traverse(m); - elem(0, n.prefix, n.label, n.attributes, n.scope, NodeSeq.fromSeq(n.child)); - elemEnd(0, n.prefix, n.label); + traverse(m) + elem(0, n.prefix, n.label, n.attributes, n.scope, NodeSeq.fromSeq(n.child)) + elemEnd(0, n.prefix, n.label) } } diff --git a/src/library/scala/xml/PrettyPrinter.scala b/src/library/scala/xml/PrettyPrinter.scala index 60ac1b5730..e87da77b9e 100644 --- a/src/library/scala/xml/PrettyPrinter.scala +++ b/src/library/scala/xml/PrettyPrinter.scala @@ -8,171 +8,181 @@ // $Id$ -package scala.xml; +package scala.xml +import scala.collection.Map import scala.runtime.compat.StringBuilder -import scala.collection.Map ; /** Class for pretty printing. After instantiating, you can use the * toPrettyXML methods to convert XML to a formatted string. The class * can be reused to pretty print any number of XML nodes. * - * @param width the width to fit the output into - * @step indentation -**/ - + * @author Burak Emir + * @version 1.0 + * + * @param width the width to fit the output into + * @step indentation + */ class PrettyPrinter( width:Int, step:Int ) { - class BrokenException() extends java.lang.Exception(); + class BrokenException() extends java.lang.Exception - class Item ; + class Item case object Break extends Item { - override def toString() = "\\"; - }; - case class Box( col:Int, s:String ) extends Item; - case class Para( s:String ) extends Item; + override def toString() = "\\" + } + case class Box(col: Int, s: String) extends Item + case class Para(s: String) extends Item - protected var items:List[Item] = Nil; + protected var items: List[Item] = Nil - protected var cur = 0; - //protected var pmap:Map[String,String] = _; + protected var cur = 0 + //protected var pmap:Map[String,String] = _ protected def reset() = { - cur = 0; - items = Nil; + cur = 0 + items = Nil } - /* try to cut at whitespace */ - protected def cut( s:String, ind:Int ):List[Item] = { - val tmp = width - cur; - if( s.length() < tmp ) - return List(Box(ind,s)); - val sb = new StringBuilder(); - var i = s.indexOf(' '); - if(i > tmp || i == -1) throw new BrokenException(); // cannot break - - var last:List[Int] = Nil; - while(i < tmp) { - last = i::last; - i = s.indexOf(' ', i ); + /** Try to cut at whitespace. + * + * @param s ... + * @param ind ... + * @return ... + */ + protected def cut(s: String, ind: Int): List[Item] = { + val tmp = width - cur + if (s.length() < tmp) + return List(Box(ind, s)) + val sb = new StringBuilder() + var i = s.indexOf(' ') + if (i > tmp || i == -1) throw new BrokenException() // cannot break + + var last: List[Int] = Nil + while (i < tmp) { + last = i::last + i = s.indexOf(' ', i) } - var res:List[Item] = Nil; - while( Nil != last ) try { - val b = Box( ind, s.substring( 0, last.head )); - cur = ind; - res = b :: Break :: cut( s.substring( last.head, s.length()), ind ); - // backtrac + var res: List[Item] = Nil + while (Nil != last) try { + val b = Box(ind, s.substring(0, last.head)) + cur = ind + res = b :: Break :: cut(s.substring(last.head, s.length()), ind) + // backtrack } catch { - case _:BrokenException => last = last.tail; + case _:BrokenException => last = last.tail } throw new BrokenException() } - /** try to make indented box, if possible, else para */ - protected def makeBox( ind:Int, s:String ) = { - if( cur < ind ) - cur == ind; - if( cur + s.length() > width ) { // fits in this line - items = Box( ind, s ) :: items; + /** Try to make indented box, if possible, else para. + * + * @param ind ... + * @param s ... + * @return ... + */ + protected def makeBox(ind: Int, s: String) = { + if (cur < ind) + cur == ind + if (cur + s.length() > width) { // fits in this line + items = Box( ind, s ) :: items cur = cur + s.length() } else try { - for( val b <- cut( s, ind ).elements ) // break it up + for (val b <- cut(s, ind).elements) // break it up items = b :: items } catch { - case _:BrokenException => makePara( ind, s ); // give up, para + case _:BrokenException => makePara(ind, s) // give up, para } } // dont respect indent in para, but afterwards - protected def makePara( ind:Int, s:String ) = { - items = Break::Para( s )::Break::items; - cur = ind; + protected def makePara(ind: Int, s: String) = { + items = Break::Para(s)::Break::items + cur = ind } // respect indent protected def makeBreak() = { // using wrapping here... - items = Break::items; - cur = 0; + items = Break :: items + cur = 0 } - protected def leafTag( n:Node ) = { - val sb = new StringBuilder().append('<'); - n.nameToString(sb); + /** + * @param n ... + * @return ... + */ + protected def leafTag(n: Node) = { + val sb = new StringBuilder("<") + n.nameToString(sb) //Utility.appendPrefixedName( n.prefix, n.label, pmap, sb ); - n.attributes.toString(sb); + n.attributes.toString(sb) //Utility.attr2xml( n.scope, n.attributes, pmap, sb ); - sb.append("/>"); - sb.toString(); + sb.append("/>") + sb.toString() } protected def startTag(n: Node, pscope: NamespaceBinding): Pair[String, Int] = { - val sb = new StringBuilder().append('<'); - n.nameToString(sb); //Utility.appendPrefixedName( n.prefix, n.label, pmap, sb ); - val i = sb.length() + 1; - n.attributes.toString(sb); - n.scope.toString(sb, pscope); - sb.append('>'); - Pair(sb.toString(), i); + val sb = new StringBuilder("<") + n.nameToString(sb) //Utility.appendPrefixedName( n.prefix, n.label, pmap, sb ); + val i = sb.length() + 1 + n.attributes.toString(sb) + n.scope.toString(sb, pscope) + sb.append('>') + Pair(sb.toString(), i) } protected def endTag(n: Node) = { - val sb = new StringBuilder().append("</"); - n.nameToString(sb); //Utility.appendPrefixedName( n.prefix, n.label, pmap, sb ); - sb.append('>'); - sb.toString(); + val sb = new StringBuilder("</") + n.nameToString(sb) //Utility.appendPrefixedName( n.prefix, n.label, pmap, sb ); + sb.append('>') + sb.toString() } - protected def childrenAreLeaves(n: Node): Boolean = { - val it = n.child.elements; - while( it.hasNext ) + val it = n.child.elements + while (it.hasNext) it.next match { case _:Atom[Any] | _:Comment | _:EntityRef | _:ProcInstr => case _:Node => - return false; + return false } - return true; + true } - - protected def fits(test: String) = { - test.length() < width - cur; - } + protected def fits(test: String) = + test.length() < width - cur /** @param tail: what we'd like to sqeeze in */ protected def traverse(node: Node, pscope: NamespaceBinding, ind: Int): Unit = node match { case Text(s) if s.trim() == "" => - + ; case _:Atom[Any] | _:Comment | _:EntityRef | _:ProcInstr => - makeBox( ind, node.toString().trim() ); - + makeBox( ind, node.toString().trim() ) case _ => val test = { - val sb = new StringBuilder(); - Utility.toXML(node, pscope, sb, false); - if(node.attribute("http://www.w3.org/XML/1998/namespace", "space") == "preserve") - sb.toString(); - else - TextBuffer.fromString(sb.toString()).toText(0)._data; - }; - if(childrenAreLeaves(node) && fits(test)) { - makeBox( ind, test ); + val sb = new StringBuilder() + Utility.toXML(node, pscope, sb, false) + if (node.attribute("http://www.w3.org/XML/1998/namespace", "space") == "preserve") + sb.toString() + else + TextBuffer.fromString(sb.toString()).toText(0)._data + } + if (childrenAreLeaves(node) && fits(test)) { + makeBox(ind, test) } else { - val Pair(stg, len2) = startTag( node, pscope ); - val etg = endTag( node ); - if( stg.length() < width - cur ) { // start tag fits - - makeBox( ind, stg ); - makeBreak(); - traverse( node.child.elements, node.scope, ind + step ); - makeBox( ind, etg ); - - } else if( len2 < width - cur ) { + val Pair(stg, len2) = startTag(node, pscope) + val etg = endTag(node) + if (stg.length() < width - cur) { // start tag fits + makeBox(ind, stg) + makeBreak() + traverse(node.child.elements, node.scope, ind + step) + makeBox(ind, etg) + } else if (len2 < width - cur) { // <start label + attrs + tag + content + end tag - makeBox( ind, stg.substring( 0, len2 )); - makeBreak(); // todo: break the rest in pieces + makeBox(ind, stg.substring(0, len2)) + makeBreak() // todo: break the rest in pieces /*{ //@todo val sq:Seq[String] = stg.split(" "); val it = sq.elements; @@ -182,44 +192,43 @@ class PrettyPrinter( width:Int, step:Int ) { makeBreak(); } }*/ - makeBox( ind, stg.substring( len2, stg.length() )); - makeBreak(); - traverse( node.child.elements, node.scope, ind + step ); - makeBox( cur, etg ); + makeBox(ind, stg.substring(len2, stg.length())) + makeBreak() + traverse(node.child.elements, node.scope, ind + step) + makeBox(cur, etg) } else { // give up - makeBox( ind, test ); - makeBreak(); + makeBox(ind, test) + makeBreak() } } } - protected def traverse( it:Iterator[Node], scope:NamespaceBinding, ind: Int ): Unit = { - for( val c <- it ) { - traverse( c, scope, ind ); - makeBreak(); + protected def traverse(it: Iterator[Node], scope: NamespaceBinding, ind: Int ): Unit = + for (val c <- it) { + traverse(c, scope, ind) + makeBreak() } - } - /** appends a formatted string containing well-formed XML with - * given namespace to prefix mapping to the given stringbuffer - * @param n the node to be serialized + /** Appends a formatted string containing well-formed XML with + * given namespace to prefix mapping to the given string buffer. + * + * @param n the node to be serialized * @param pmap the namespace to prefix mapping - * @param sb the stringbuffer to append to + * @param sb the stringbuffer to append to */ - def format(n: Node, sb: StringBuilder ): Unit = { // entry point - format(n,null,sb) - } - - def format(n: Node, pscope:NamespaceBinding, sb: StringBuilder): Unit = { // entry point - var lastwasbreak = false; - reset(); - traverse( n, pscope, 0 ); - var cur = 0; - for( val b <- items.reverse ) b match { + def format(n: Node, sb: StringBuilder ): Unit = // entry point + format(n, null, sb) + + def format(n: Node, pscope: NamespaceBinding, sb: StringBuilder): Unit = { // entry point + var lastwasbreak = false + reset() + traverse(n, pscope, 0) + var cur = 0 + for (val b <- items.reverse) b match { case Break => - if(!lastwasbreak) sb.append('\n'); // on windows: \r\n ? + if (!lastwasbreak) sb.append('\n') // on windows: \r\n ? lastwasbreak = true - cur = 0; + cur = 0 // while( cur < last ) { // sb.append(' '); // cur = cur + 1; @@ -227,14 +236,14 @@ class PrettyPrinter( width:Int, step:Int ) { case Box(i, s) => lastwasbreak = false - while( cur < i ) { - sb.append(' '); - cur = cur + 1; + while (cur < i) { + sb.append(' ') + cur = cur + 1 } - sb.append( s ); + sb.append(s) case Para( s ) => lastwasbreak = false - sb.append( s ); + sb.append(s) } } @@ -242,47 +251,55 @@ class PrettyPrinter( width:Int, step:Int ) { /** returns a formatted string containing well-formed XML with * default namespace prefix mapping + * * @param n the node to be serialized + * @return ... */ - def format(n: Node): String = format(n, null); //Utility.defaultPrefixes( n )); - - /** returns a formatted string containing well-formed XML with - * given namespace to prefix mapping - * @param n the node to be serialized - * @param pmap the namespace to prefix mapping + def format(n: Node): String = format(n, null) //Utility.defaultPrefixes(n)) + + /** Returns a formatted string containing well-formed XML with + * given namespace to prefix mapping. + * + * @param n the node to be serialized + * @param pmap the namespace to prefix mapping + * @return ... */ def format(n: Node, pscope: NamespaceBinding): String = { - val sb = new StringBuilder(); - format( n, pscope, sb ); - sb.toString(); + val sb = new StringBuilder() + format(n, pscope, sb) + sb.toString() } - /* returns a formatted string containing well-formed XML nodes with - * default namespace prefix mapping - */ - def formatNodes( nodes:Seq[Node] ):String = { + /** Returns a formatted string containing well-formed XML nodes with + * default namespace prefix mapping. + * + * @param nodes ... + * @return ... + */ + def formatNodes(nodes: Seq[Node]): String = formatNodes(nodes, null) - } - /** returns a formatted string containing well-formed XML - * @param nodes the sequence of nodes to be serialized - * @param pmap the namespace to prefix mapping + /** Returns a formatted string containing well-formed XML. + * + * @param nodes the sequence of nodes to be serialized + * @param pmap the namespace to prefix mapping */ - def formatNodes( nodes:Seq[Node], pscope: NamespaceBinding ):String = { - var sb = new StringBuilder(); - formatNodes( nodes, pscope, sb ); - sb.toString(); + def formatNodes(nodes: Seq[Node], pscope: NamespaceBinding): String = { + var sb = new StringBuilder() + formatNodes(nodes, pscope, sb) + sb.toString() } - /** appends a formatted string containing well-formed XML with - * the given namespace to prefix mapping to the given stringbuffer - * @param n the node to be serialized - * @param pmap the namespace to prefix mapping - * @param sb the string buffer to which to append to + /** Appends a formatted string containing well-formed XML with + * the given namespace to prefix mapping to the given stringbuffer. + * + * @param n the node to be serialized + * @param pmap the namespace to prefix mapping + * @param sb the string buffer to which to append to */ - def formatNodes( nodes: Seq[Node], pscope: NamespaceBinding, sb: StringBuilder ): Unit = { - for( val n <- nodes.elements ) { - sb.append(format( n, pscope )) + def formatNodes(nodes: Seq[Node], pscope: NamespaceBinding, sb: StringBuilder): Unit = + for (val n <- nodes.elements) { + sb.append(format(n, pscope)) } - } + } diff --git a/src/library/scala/xml/parsing/ConstructingHandler.scala b/src/library/scala/xml/parsing/ConstructingHandler.scala index aaa1bf2ad9..93f8a07c92 100644 --- a/src/library/scala/xml/parsing/ConstructingHandler.scala +++ b/src/library/scala/xml/parsing/ConstructingHandler.scala @@ -9,28 +9,30 @@ // $Id$ -package scala.xml.parsing; +package scala.xml.parsing - -/** implementation of MarkupHandler that constructs nodes */ +/** Implementation of MarkupHandler that constructs nodes. + * + * @author Burak Emir + * @version 1.0 + */ abstract class ConstructingHandler extends MarkupHandler { - val preserveWS: Boolean; + val preserveWS: Boolean def elem(pos: int, pre: String, label: String, attrs: MetaData, pscope: NamespaceBinding, nodes: NodeSeq): NodeSeq = - Elem(pre, label, attrs, pscope, nodes:_*); - + Elem(pre, label, attrs, pscope, nodes:_*) - def procInstr(pos: Int, target: String, txt: String ) = - ProcInstr(target, txt); + def procInstr(pos: Int, target: String, txt: String) = + ProcInstr(target, txt) - def comment(pos: Int, txt: String ) = - Comment( txt ); + def comment(pos: Int, txt: String) = + Comment(txt) def entityRef(pos: Int, n: String) = - EntityRef( n ); + EntityRef(n) def text(pos: Int, txt:String) = - Text( txt ); + Text(txt) } diff --git a/src/library/scala/xml/parsing/ConstructingParser.scala b/src/library/scala/xml/parsing/ConstructingParser.scala index adef5ef1ad..b7c88c79ec 100644 --- a/src/library/scala/xml/parsing/ConstructingParser.scala +++ b/src/library/scala/xml/parsing/ConstructingParser.scala @@ -9,28 +9,31 @@ // $Id$ -package scala.xml.parsing; +package scala.xml.parsing +import java.io.File -import scala.io.Source; +import scala.io.Source object ConstructingParser { - def fromFile(inp: java.io.File, preserveWS: Boolean) = { - val p = new ConstructingParser(Source.fromFile(inp), preserveWS); - p.nextch; + def fromFile(inp: File, preserveWS: Boolean) = { + val p = new ConstructingParser(Source.fromFile(inp), preserveWS) + p.nextch p } - def fromSource(inp: scala.io.Source, preserveWS: Boolean) = { - val p = new ConstructingParser(inp, preserveWS); - p.nextch; + def fromSource(inp: Source, preserveWS: Boolean) = { + val p = new ConstructingParser(inp, preserveWS) + p.nextch p } } -/** an xml parser. parses XML and invokes callback methods of a MarkupHandler. Don't forget to call next.ch on a freshly - * instantiated parser in order to initialize it. If you get the parser from the object method, initialization is already done for you. +/** An xml parser. parses XML and invokes callback methods of a MarkupHandler. + * Don't forget to call next.ch on a freshly instantiated parser in order to + * initialize it. If you get the parser from the object method, initialization + * is already done for you. * *<pre> object parseFromURL { @@ -56,9 +59,9 @@ with ExternalSources with MarkupParser { // default impl. of Logged - override def log(msg:String): Unit = {} + override def log(msg: String): Unit = {} - val preserveWS = presWS; - val input = inp; + val preserveWS = presWS + val input = inp } diff --git a/src/library/scala/xml/parsing/MarkupHandler.scala b/src/library/scala/xml/parsing/MarkupHandler.scala index ab7c3799a2..5d7577d752 100644 --- a/src/library/scala/xml/parsing/MarkupHandler.scala +++ b/src/library/scala/xml/parsing/MarkupHandler.scala @@ -9,18 +9,19 @@ // $Id$ -package scala.xml.parsing; +package scala.xml.parsing - -import scala.io.Source; -import scala.collection.mutable.{ HashMap, Map } -import scala.xml.dtd._ ; - -import scala.util.logging._; +import scala.collection.mutable.{HashMap, Map} +import scala.io.Source +import scala.xml.dtd._ +import scala.util.logging.Logged /** class that handles markup - provides callback methods to MarkupParser. * the default is nonvalidating behaviour * + * @author Burak Emir + * @version 1.0 + * * @todo can we ignore more entity declarations (i.e. those with extIDs)? * @todo expanding entity references */ @@ -30,32 +31,31 @@ abstract class MarkupHandler extends AnyRef with Logged { //def log(msg:String) = {} /** returns true is this markup handler is validing */ - val isValidating: Boolean = false; + val isValidating: Boolean = false - var decls: List[Decl] = Nil; + var decls: List[Decl] = Nil - var ent: Map[String, EntityDecl] = new HashMap[String, EntityDecl](); + var ent: Map[String, EntityDecl] = new HashMap[String, EntityDecl]() def lookupElemDecl(Label: String): ElemDecl = { def lookup(xs:List[Decl]): ElemDecl = xs match { - case (z @ ElemDecl(Label, _)) :: zs => return z; - case _::zs => lookup(zs); + case (z @ ElemDecl(Label, _)) :: zs => return z + case _::zs => lookup(zs) case _ => return null } lookup(decls) } - def replacementText( entityName: String ): Source = ent.get(entityName) match { - case Some(ParsedEntityDecl(_, IntDef(value))) => - Source.fromString(value); - case Some(ParameterEntityDecl(_, IntDef(value))) => - Source.fromString(" "+value+" "); - case Some(_) => - Source.fromString("<!-- "+entityName+"; -->"); - case None => - Source.fromString("<!-- unknown entity "+entityName+"; -->") - } - + def replacementText(entityName: String): Source = ent.get(entityName) match { + case Some(ParsedEntityDecl(_, IntDef(value))) => + Source.fromString(value) + case Some(ParameterEntityDecl(_, IntDef(value))) => + Source.fromString(" "+value+" ") + case Some(_) => + Source.fromString("<!-- "+entityName+"; -->") + case None => + Source.fromString("<!-- unknown entity "+entityName+"; -->") + } //def checkChildren(pos:int, pre: String, label:String,ns:NodeSeq): Unit = {} @@ -72,7 +72,7 @@ abstract class MarkupHandler extends AnyRef with Logged { /** callback method invoked by MarkupParser after end-tag of element. * - * @param pos the position in the sourcefile + * @param pos the position in the source file * @param pre the prefix * @param label the local name * @param attrs the attributes (metadata) @@ -82,31 +82,40 @@ abstract class MarkupHandler extends AnyRef with Logged { /** callback method invoked by MarkupParser after parsing an elementm, * between the elemStart and elemEnd callbacks * - * - * @param pos the position in the sourcefile + * @param pos the position in the source file * @param pre the prefix * @param label the local name * @param attrs the attributes (metadata) * @param args the children of this element + * @return ... */ - def elem(pos: int, pre: String, label: String, attrs: MetaData, scope:NamespaceBinding, args: NodeSeq): NodeSeq; + def elem(pos: int, pre: String, label: String, attrs: MetaData, scope: NamespaceBinding, args: NodeSeq): NodeSeq /** callback method invoked by MarkupParser after parsing PI. + * + * @param pos the position in the source file + * @param target ... + * @param txt ... + * @return ... */ - def procInstr(pos: Int, target: String, txt: String): NodeSeq; + def procInstr(pos: Int, target: String, txt: String): NodeSeq /** callback method invoked by MarkupParser after parsing comment. + * + * @param pos the position in the source file + * @param comment ... + * @return ... */ - def comment(pos: Int, comment: String ): NodeSeq; + def comment(pos: Int, comment: String): NodeSeq /** callback method invoked by MarkupParser after parsing entity ref. * @todo expanding entity references */ - def entityRef(pos: Int, n: String): NodeSeq; + def entityRef(pos: Int, n: String): NodeSeq /** callback method invoked by MarkupParser after parsing text. */ - def text(pos: Int, txt:String): NodeSeq; + def text(pos: Int, txt: String): NodeSeq // DTD handler methods @@ -120,10 +129,10 @@ abstract class MarkupHandler extends AnyRef with Logged { case _:ExtDef if !isValidating => ; // ignore (cf REC-xml 4.4.1) case _ => - val y = ParameterEntityDecl(name, edef); - decls = y :: decls; - ent.update(name, y); - //log("ent.get(..) = "+ent.get(name)); + val y = ParameterEntityDecl(name, edef) + decls = y :: decls + ent.update(name, y) + //log("ent.get(..) = "+ent.get(name)) } } @@ -131,8 +140,8 @@ abstract class MarkupHandler extends AnyRef with Logged { case _:ExtDef if !isValidating => ; // ignore (cf REC-xml 4.8 and 4.4.1) case _ => - val y = ParsedEntityDecl(name, edef); - decls = y :: decls; + val y = ParsedEntityDecl(name, edef) + decls = y :: decls ent.update(name, y) } @@ -143,10 +152,10 @@ abstract class MarkupHandler extends AnyRef with Logged { {} def peReference(name: String): Unit = - decls = PEReference( name ) :: decls; + decls = PEReference( name ) :: decls /** report a syntax error */ - def reportSyntaxError(pos: Int, str: String): Unit; + def reportSyntaxError(pos: Int, str: String): Unit } diff --git a/src/library/scala/xml/parsing/MarkupParser.scala b/src/library/scala/xml/parsing/MarkupParser.scala index 15d4bd8c40..b6bceafd23 100644 --- a/src/library/scala/xml/parsing/MarkupParser.scala +++ b/src/library/scala/xml/parsing/MarkupParser.scala @@ -9,11 +9,11 @@ // $Id$ -package scala.xml.parsing; +package scala.xml.parsing import scala.runtime.compat.StringBuilder -import scala.io.Source; -import scala.xml.dtd._ ; +import scala.io.Source +import scala.xml.dtd._ /** * An XML parser. @@ -25,49 +25,52 @@ import scala.xml.dtd._ ; * * While XML elements are returned, DTD declarations - if handled - are * collected using side-effects. + * + * @author Burak Emir + * @version 1.0 */ trait MarkupParser requires (MarkupParser with MarkupHandler) extends AnyRef with TokenTests { - val input: Source; + val input: Source /** if true, does not remove surplus whitespace */ - val preserveWS: Boolean; + val preserveWS: Boolean - def externalSource(systemLiteral: String): Source; + def externalSource(systemLiteral: String): Source // // variables, values // - var curInput: Source = input; + var curInput: Source = input /** the handler of the markup, returns this */ - private val handle: MarkupHandler = this; + private val handle: MarkupHandler = this /** stack of inputs */ - var inpStack: List[Source] = Nil; + var inpStack: List[Source] = Nil /** holds the position in the source file */ - var pos: Int = _; + var pos: Int = _ /* used when reading external subset */ - var extIndex = -1; + var extIndex = -1 /** holds temporary values of pos */ - var tmppos: Int = _; + var tmppos: Int = _ /** holds the next character */ - var ch: Char = _; + var ch: Char = _ /** character buffer, for names */ - protected val cbuf = new StringBuilder(); + protected val cbuf = new StringBuilder() - var dtd: DTD = null; + var dtd: DTD = null - protected var doc: Document = null; + protected var doc: Document = null - var eof: Boolean = false; + var eof: Boolean = false // // methods @@ -76,13 +79,13 @@ trait MarkupParser requires (MarkupParser with MarkupHandler) extends AnyRef wit /** <? prolog ::= xml S ... ?> */ def xmlProcInstr(): MetaData = { - xToken("xml"); - xSpace; - val Pair(md,scp) = xAttributes(TopScope); - if(scp != TopScope) + xToken("xml") + xSpace + val Pair(md,scp) = xAttributes(TopScope) + if (scp != TopScope) reportSyntaxError("no xmlns definitions here, please."); - xToken('?'); - xToken('>'); + xToken('?') + xToken('>') md } @@ -91,39 +94,40 @@ trait MarkupParser requires (MarkupParser with MarkupHandler) extends AnyRef wit */ def prolog(): Tuple3[Option[String], Option[String], Option[Boolean]] = { - //Console.println("(DEBUG) prolog"); - var n = 0; - var info_ver: Option[String] = None; - var info_enc: Option[String] = None; - var info_stdl: Option[Boolean] = None; + //Console.println("(DEBUG) prolog") + var n = 0 + var info_ver: Option[String] = None + var info_enc: Option[String] = None + var info_stdl: Option[Boolean] = None - var m = xmlProcInstr(); + var m = xmlProcInstr() - xSpace; + xSpace m("version") match { case null => ; - case Text("1.0") => info_ver = Some("1.0"); n = n + 1; - case _ => reportSyntaxError("cannot deal with versions != 1.0"); + case Text("1.0") => info_ver = Some("1.0"); n = n + 1 + case _ => reportSyntaxError("cannot deal with versions != 1.0") } m("encoding") match { case null => ; - case Text(enc) => if (!isValidIANAEncoding(enc.toString())) - reportSyntaxError("\"" + enc + "\" is not a valid encoding"); - else { - info_enc = Some(enc.toString()); - n = n + 1; - } + case Text(enc) => + if (!isValidIANAEncoding(enc.toString())) + reportSyntaxError("\"" + enc + "\" is not a valid encoding") + else { + info_enc = Some(enc.toString()) + n = n + 1 + } } m("standalone") match { case null => ; - case Text("yes") => info_stdl = Some(true); n = n + 1; - case Text("no") => info_stdl = Some(false); n = n + 1; - case _ => reportSyntaxError("either 'yes' or 'no' expected"); + case Text("yes") => info_stdl = Some(true); n = n + 1 + case Text("no") => info_stdl = Some(false); n = n + 1 + case _ => reportSyntaxError("either 'yes' or 'no' expected") } - if(m.length - n != 0) { + if (m.length - n != 0) { reportSyntaxError("VersionInfo EncodingDecl? SDDecl? or '?>' expected!"); } //Console.println("[MarkupParser::prolog] finished parsing prolog!"); @@ -133,29 +137,30 @@ trait MarkupParser requires (MarkupParser with MarkupHandler) extends AnyRef wit /** prolog, but without standalone */ def textDecl(): Tuple2[Option[String],Option[String]] = { - var info_ver: Option[String] = None; - var info_enc: Option[String] = None; + var info_ver: Option[String] = None + var info_enc: Option[String] = None - var m = xmlProcInstr(); - var n = 0; + var m = xmlProcInstr() + var n = 0 m("version") match { case null => ; - case Text("1.0") => info_ver = Some("1.0"); n = n + 1; - case _ => reportSyntaxError("cannot deal with versions != 1.0"); + case Text("1.0") => info_ver = Some("1.0"); n = n + 1 + case _ => reportSyntaxError("cannot deal with versions != 1.0") } m("encoding") match { case null => ; - case Text(enc) => if (!isValidIANAEncoding(enc.toString())) - reportSyntaxError("\"" + enc + "\" is not a valid encoding"); - else { - info_enc = Some(enc.toString()); - n = n + 1; - } + case Text(enc) => + if (!isValidIANAEncoding(enc.toString())) + reportSyntaxError("\"" + enc + "\" is not a valid encoding") + else { + info_enc = Some(enc.toString()) + n = n + 1 + } } - if(m.length - n != 0) { + if (m.length - n != 0) { reportSyntaxError("VersionInfo EncodingDecl? or '?>' expected!"); } //Console.println("[MarkupParser::textDecl] finished parsing textdecl"); @@ -173,18 +178,18 @@ trait MarkupParser requires (MarkupParser with MarkupHandler) extends AnyRef wit def document(): Document = { - //Console.println("(DEBUG) document"); - doc = new Document(); + //Console.println("(DEBUG) document") + doc = new Document() - this.dtd = null; + this.dtd = null var info_prolog: Tuple3[Option[String], Option[String], Option[Boolean]] = Tuple3(None, None, None); if ('<' != ch) { - reportSyntaxError("< expected"); - return null; + reportSyntaxError("< expected") + return null } - nextch; // is prolog ? - var children: NodeSeq = null; + nextch // is prolog ? + var children: NodeSeq = null if ('?' == ch) { //Console.println("[MarkupParser::document] starts with xml declaration"); nextch; @@ -193,8 +198,7 @@ trait MarkupParser requires (MarkupParser with MarkupHandler) extends AnyRef wit doc.encoding = info_prolog._2 doc.standAlone = info_prolog._3 - children = content(TopScope); // DTD handled as side effect - + children = content(TopScope) // DTD handled as side effect } else { //Console.println("[MarkupParser::document] does not start with xml declaration"); // @@ -220,34 +224,34 @@ trait MarkupParser requires (MarkupParser with MarkupHandler) extends AnyRef wit theNode = m; } if (1 != elemCount) { - reportSyntaxError("document must contain exactly one element"); - Console.println(children.toList); + reportSyntaxError("document must contain exactly one element") + Console.println(children.toList) } - doc.children = children; - doc.docElem = theNode; - return doc + doc.children = children + doc.docElem = theNode + doc } /** append Unicode character to name buffer*/ - protected def putChar(c: Char) = cbuf.append(c); + protected def putChar(c: Char) = cbuf.append(c) //var xEmbeddedBlock = false; /** this method assign the next character to ch and advances in input */ def nextch: Unit = { if (curInput.hasNext) { - ch = curInput.next; - pos = curInput.pos; + ch = curInput.next + pos = curInput.pos } else { val ilen = inpStack.length; //Console.println(" ilen = "+ilen+ " extIndex = "+extIndex); if ((ilen != extIndex) && (ilen > 0)) { /** for external source, inpStack == Nil ! need notify of eof! */ - pop(); + pop() } else { - eof = true; - ch = 0.asInstanceOf[Char]; + eof = true + ch = 0.asInstanceOf[Char] } } } @@ -258,10 +262,10 @@ trait MarkupParser requires (MarkupParser with MarkupHandler) extends AnyRef wit */ def xToken(that: Char): Unit = { if (ch == that) - nextch; + nextch else { - reportSyntaxError("'" + that + "' expected instead of '" + ch + "'"); - error("FATAL"); + reportSyntaxError("'" + that + "' expected instead of '" + ch + "'") + error("FATAL") } } @@ -275,14 +279,14 @@ trait MarkupParser requires (MarkupParser with MarkupHandler) extends AnyRef wit * [41] Attributes ::= { S Name Eq AttValue } */ def xAttributes(pscope:NamespaceBinding): Pair[MetaData,NamespaceBinding] = { - var scope: NamespaceBinding = pscope; - var aMap: MetaData = Null; + var scope: NamespaceBinding = pscope + var aMap: MetaData = Null while (isNameStart(ch)) { - val pos = this.pos; + val pos = this.pos - val qname = xName; - val _ = xEQ; - val value = xAttributeValue(); + val qname = xName + val _ = xEQ + val value = xAttributeValue() Utility.prefix(qname) match { case Some("xmlns") => @@ -315,21 +319,20 @@ trait MarkupParser requires (MarkupParser with MarkupHandler) extends AnyRef wit * | `"` { _ } `"` */ def xAttributeValue(): String = { - val endch = ch; - nextch; + val endch = ch + nextch while (ch != endch) { if ('<' == ch) reportSyntaxError( "'<' not allowed in attrib value" ); - putChar(ch); - nextch; + putChar(ch) + nextch } - nextch; - val str = cbuf.toString(); - cbuf.setLength(0); + nextch + val str = cbuf.toString() + cbuf.setLength(0) // well-formedness constraint normalizeAttributeValue(str) - } /** entity value, terminated by either ' or ". value may not contain <. @@ -337,15 +340,15 @@ trait MarkupParser requires (MarkupParser with MarkupHandler) extends AnyRef wit * | `"` { _ } `"` */ def xEntityValue(): String = { - val endch = ch; - nextch; + val endch = ch + nextch while (ch != endch) { - putChar(ch); - nextch; + putChar(ch) + nextch } - nextch; - val str = cbuf.toString(); - cbuf.setLength(0); + nextch + val str = cbuf.toString() + cbuf.setLength(0) str } @@ -355,26 +358,26 @@ trait MarkupParser requires (MarkupParser with MarkupHandler) extends AnyRef wit * [44] EmptyElemTag ::= '<' Name { S Attribute } [S] */ protected def xTag(pscope:NamespaceBinding): Tuple3[String, MetaData, NamespaceBinding] = { - val qname = xName; + val qname = xName - xSpaceOpt; + xSpaceOpt val Pair(aMap: MetaData, scope: NamespaceBinding) = { if (isNameStart(ch)) xAttributes(pscope) else Pair(Null, pscope) } - Triple(qname, aMap, scope); + Triple(qname, aMap, scope) } /** [42] '<' xmlEndTag ::= '<' '/' Name S? '>' */ def xEndTag(n: String) = { - xToken('/'); - val m = xName; + xToken('/') + val m = xName if (n != m) reportSyntaxError("expected closing tag of " + n/* +", not "+m*/); - xSpaceOpt; + xSpaceOpt xToken('>') } @@ -383,9 +386,9 @@ trait MarkupParser requires (MarkupParser with MarkupHandler) extends AnyRef wit * see [15] */ def xCharData: NodeSeq = { - xToken("[CDATA["); - val pos1 = pos; - val sb: StringBuilder = new StringBuilder(); + xToken("[CDATA[") + val pos1 = pos + val sb: StringBuilder = new StringBuilder() while (true) { if (ch==']' && { sb.append(ch); nextch; ch == ']' } && @@ -462,28 +465,27 @@ trait MarkupParser requires (MarkupParser with MarkupHandler) extends AnyRef wit } /** '<' content1 ::= ... */ - def content1(pscope: NamespaceBinding, ts: NodeBuffer): Unit = { + def content1(pscope: NamespaceBinding, ts: NodeBuffer): Unit = ch match { case '!' => - nextch; + nextch if ('[' == ch) // CDATA - ts &+ xCharData; + ts &+ xCharData else if ('D' == ch) // doctypedecl, parse DTD // @todo REMOVE HACK - parseDTD(); + parseDTD() else // comment - ts &+ xComment; - case '?' => // PI - nextch; - ts &+ xProcInstr; + ts &+ xComment + case '?' => // PI + nextch + ts &+ xProcInstr case _ => - ts &+ element1(pscope); // child + ts &+ element1(pscope) // child } - } /** content1 ::= '<' content1 | '&' charref ... */ def content(pscope: NamespaceBinding): NodeSeq = { - var ts = new NodeBuffer; - var exit = eof; + var ts = new NodeBuffer + var exit = eof while (! exit) { //Console.println("in content, ch = '"+ch+"' line="+scala.io.Position.line(pos)); /* if( xEmbeddedBlock ) { @@ -521,18 +523,18 @@ trait MarkupParser requires (MarkupParser with MarkupHandler) extends AnyRef wit xToken(';'); ts &+ theChar ; case _ => // EntityRef - val n = xName ; - xToken(';'); + val n = xName + xToken(';') n match { - case "lt" => ts &+ '<'; - case "gt" => ts &+ '>'; - case "amp" => ts &+ '&'; - case "quote" => ts &+ '"'; + case "lt" => ts &+ '<' + case "gt" => ts &+ '>' + case "amp" => ts &+ '&' + case "quote" => ts &+ '"' case _ => /* ts + handle.entityRef( tmppos, n ) ; */ - push( n ); + push(n) } } case _ => // text content @@ -542,10 +544,10 @@ trait MarkupParser requires (MarkupParser with MarkupHandler) extends AnyRef wit } /*}*/ } - val list = ts.toList; + val list = ts.toList // 2do: optimize seq repr. new NodeSeq { - val theSeq = list; + val theSeq = list } } // content(NamespaceBinding) @@ -555,18 +557,18 @@ trait MarkupParser requires (MarkupParser with MarkupHandler) extends AnyRef wit def externalID(): ExternalID = ch match { case 'S' => - nextch; - xToken("YSTEM"); - xSpace; - val sysID = systemLiteral(); - new SystemID(sysID); + nextch + xToken("YSTEM") + xSpace + val sysID = systemLiteral() + new SystemID(sysID) case 'P' => - nextch; xToken("UBLIC"); - xSpace; - val pubID = pubidLiteral(); - xSpace; - val sysID = systemLiteral(); - new PublicID(pubID, sysID); + nextch; xToken("UBLIC") + xSpace + val pubID = pubidLiteral() + xSpace + val sysID = systemLiteral() + new PublicID(pubID, sysID) } @@ -577,28 +579,28 @@ trait MarkupParser requires (MarkupParser with MarkupHandler) extends AnyRef wit */ def parseDTD(): Unit = { // dirty but fast //Console.println("(DEBUG) parseDTD"); - var extID: ExternalID = null; + var extID: ExternalID = null if (this.dtd != null) reportSyntaxError("unexpected character (DOCTYPE already defined"); - xToken("DOCTYPE"); - xSpace; - val n = xName; - xSpace; + xToken("DOCTYPE") + xSpace + val n = xName + xSpace //external ID - if('S' == ch || 'P' == ch) { - extID = externalID(); - xSpaceOpt; + if ('S' == ch || 'P' == ch) { + extID = externalID() + xSpaceOpt } /* parse external subset of DTD */ - if((null != extID)&&(isValidating)) { + if ((null != extID) && isValidating) { - pushExternal(extID.systemId); + pushExternal(extID.systemId) //val extSubsetSrc = externalSource( extID.systemId ); - extIndex = inpStack.length; + extIndex = inpStack.length /* .indexOf(':') != -1) { // assume URI Source.fromFile(new java.net.URI(extID.systemLiteral)); @@ -614,11 +616,11 @@ trait MarkupParser requires (MarkupParser with MarkupHandler) extends AnyRef wit //pos = 0; //nextch; - extSubset(); + extSubset() - pop(); + pop() - extIndex = -1; + extIndex = -1 //curInput = old; //pos = curInput.pos; @@ -631,60 +633,60 @@ trait MarkupParser requires (MarkupParser with MarkupHandler) extends AnyRef wit } if ('[' == ch) { // internal subset - nextch; + nextch /* TODO */ //Console.println("hello"); - intSubset(); + intSubset() //while(']' != ch) // nextch; // TODO: do the DTD parsing?? ?!?!?!?!! - xToken(']'); - xSpaceOpt; + xToken(']') + xSpaceOpt } - xToken('>'); + xToken('>') this.dtd = new DTD { - /*override var*/ externalID = extID; - /*override val */decls = handle.decls.reverse; + /*override var*/ externalID = extID + /*override val */decls = handle.decls.reverse } //this.dtd.initializeEntities(); - if(doc!=null) + if (doc!=null) doc.dtd = this.dtd - handle.endDTD(n); + handle.endDTD(n) } def element(pscope: NamespaceBinding): NodeSeq = { - xToken('<'); - element1(pscope); + xToken('<') + element1(pscope) } /** '<' element ::= xmlTag1 '>' { xmlExpr | '{' simpleExpr '}' } ETag * | xmlTag1 '/' '>' */ def element1(pscope: NamespaceBinding): NodeSeq = { - val pos = this.pos; - val Tuple3(qname, aMap, scope) = xTag(pscope); + val pos = this.pos + val Tuple3(qname, aMap, scope) = xTag(pscope) val Tuple2(pre, local) = Utility.prefix(qname) match { - case Some(p) => Pair(p,qname.substring(p.length()+1, qname.length())); - case _ => Pair(null,qname); + case Some(p) => Pair(p,qname.substring(p.length()+1, qname.length())) + case _ => Pair(null,qname) } val ts = { if (ch == '/') { // empty element - xToken('/'); - xToken('>'); - handle.elemStart(pos, pre, local, aMap, scope); - NodeSeq.Empty; + xToken('/') + xToken('>') + handle.elemStart(pos, pre, local, aMap, scope) + NodeSeq.Empty } else { // element with content - xToken('>'); - handle.elemStart(pos, pre, local, aMap, scope); - val tmp = content(scope); - xEndTag(qname); - tmp; + xToken('>') + handle.elemStart(pos, pre, local, aMap, scope) + val tmp = content(scope) + xEndTag(qname) + tmp } } - val res = handle.elem(pos, pre, local, aMap, scope, ts ); - handle.elemEnd(pos, pre, local); + val res = handle.elem(pos, pre, local, aMap, scope, ts) + handle.elemEnd(pos, pre, local) res } @@ -697,14 +699,14 @@ trait MarkupParser requires (MarkupParser with MarkupHandler) extends AnyRef wit def xName: String = { if (isNameStart(ch)) { while (isNameChar(ch)) { - putChar(ch); - nextch; + putChar(ch) + nextch } - val n = cbuf.toString().intern(); - cbuf.setLength(0); + val n = cbuf.toString().intern() + cbuf.setLength(0) n } else { - reportSyntaxError("name expected"); + reportSyntaxError("name expected") new String() } } @@ -713,27 +715,22 @@ trait MarkupParser requires (MarkupParser with MarkupHandler) extends AnyRef wit def xEQ = { xSpaceOpt; xToken('='); xSpaceOpt } /** skip optional space S? */ - def xSpaceOpt = while (isSpace(ch) && !eof) { nextch; }; + def xSpaceOpt = while (isSpace(ch) && !eof) { nextch; } /** scan [3] S ::= (#x20 | #x9 | #xD | #xA)+ */ - def xSpace = { - if (isSpace(ch)) { - nextch; xSpaceOpt - } - else { - reportSyntaxError("whitespace expected"); - } - } + def xSpace = + if (isSpace(ch)) { nextch; xSpaceOpt } + else reportSyntaxError("whitespace expected") /** '<?' ProcInstr ::= Name [S ({Char} - ({Char}'>?' {Char})]'?>' * * see [15] */ def xProcInstr: NodeSeq = { - val sb:StringBuilder = new StringBuilder(); - val n = xName; + val sb:StringBuilder = new StringBuilder() + val n = xName if (isSpace(ch)) { - xSpace; + xSpace while (true) { if (ch == '?' && { sb.append( ch ); nextch; ch == '>' }) { sb.setLength(sb.length() - 1); @@ -744,9 +741,9 @@ trait MarkupParser requires (MarkupParser with MarkupHandler) extends AnyRef wit nextch } }; - xToken('?'); - xToken('>'); - return handle.procInstr(tmppos, n.toString(), sb.toString()); + xToken('?') + xToken('>') + handle.procInstr(tmppos, n.toString(), sb.toString()) } /** parse character data. @@ -782,37 +779,37 @@ trait MarkupParser requires (MarkupParser with MarkupHandler) extends AnyRef wit * | `"` { _ } `"` */ def systemLiteral(): String = { - val endch = ch; + val endch = ch if (ch != '\'' && ch != '"') reportSyntaxError("quote ' or \" expected"); - nextch; + nextch while (ch != endch) { - putChar(ch); - nextch; + putChar(ch) + nextch } - nextch; - val str = cbuf.toString(); - cbuf.setLength(0); + nextch + val str = cbuf.toString() + cbuf.setLength(0) str } /* [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'" */ def pubidLiteral(): String = { - val endch = ch; + val endch = ch if (ch!='\'' && ch != '"') reportSyntaxError("quote ' or \" expected"); - nextch; + nextch while (ch != endch) { - putChar(ch); + putChar(ch) //Console.println("hello '"+ch+"'"+isPubIDChar(ch)); - if(!isPubIDChar(ch)) + if (!isPubIDChar(ch)) reportSyntaxError("char '"+ch+"' is not allowed in public id"); - nextch; + nextch } - nextch; - val str = cbuf.toString(); - cbuf.setLength(0); + nextch + val str = cbuf.toString() + cbuf.setLength(0) str } @@ -822,17 +819,16 @@ trait MarkupParser requires (MarkupParser with MarkupHandler) extends AnyRef wit def extSubset(): Unit = { var textdecl:Tuple2[Option[String],Option[String]] = null; - if(ch=='<') { - nextch; - if(ch=='?') { - nextch; + if (ch=='<') { + nextch + if (ch=='?') { + nextch textdecl = textDecl() } else - markupDecl1(); - } - while(!eof) { - markupDecl(); + markupDecl1() } + while (!eof) + markupDecl() } def markupDecl1() = { @@ -842,40 +838,40 @@ trait MarkupParser requires (MarkupParser with MarkupHandler) extends AnyRef wit def doIgnore() = { xToken('['); while(']' != ch) nextch; nextch; // ']' } - if('?' == ch) { - nextch; - xProcInstr; // simply ignore processing instructions! + if ('?' == ch) { + nextch + xProcInstr // simply ignore processing instructions! } else { - xToken('!'); + xToken('!') ch match { case '-' => - xComment ; // ignore comments + xComment // ignore comments case 'E' => - nextch; + nextch if ('L' == ch) { - nextch; + nextch elementDecl() } else - entityDecl(); + entityDecl() case 'A' => - nextch; - attrDecl(); + nextch + attrDecl() case 'N' => - nextch; - notationDecl(); + nextch + notationDecl() case '[' if inpStack.length >= extIndex => - nextch; - xSpaceOpt; + nextch + xSpaceOpt ch match { case '%' => - nextch; - val ent = xName; - xToken(';'); - xSpaceOpt; + nextch + val ent = xName + xToken(';') + xSpaceOpt /* Console.println("hello, pushing!"); { @@ -883,12 +879,12 @@ trait MarkupParser requires (MarkupParser with MarkupHandler) extends AnyRef wit while(test.hasNext) Console.print(test.next); } */ - push(ent); - xSpaceOpt; + push(ent) + xSpaceOpt //Console.println("hello, getting name"); - val stmt = xName; + val stmt = xName //Console.println("hello, got name"); - xSpaceOpt; + xSpaceOpt //Console.println("how can we be eof = "+eof); // eof = true because not external?! @@ -897,128 +893,124 @@ trait MarkupParser requires (MarkupParser with MarkupHandler) extends AnyRef wit //pop(); - //Console.println("hello, popped"); stmt match { // parameter entity case "INCLUDE" => - doInclude(); + doInclude() case "IGNORE" => doIgnore() } case 'I' => - nextch; + nextch ch match { case 'G' => - nextch; - xToken("NORE"); - xSpaceOpt; + nextch + xToken("NORE") + xSpaceOpt doIgnore() case 'N' => - nextch; - xToken("NCLUDE"); + nextch + xToken("NCLUDE") doInclude() } } - xToken(']'); - xToken('>'); + xToken(']') + xToken('>') case _ => - curInput.reportError(pos, "unexpected character '"+ch+"', expected some markupdecl"); - while(ch!='>') - nextch; - + curInput.reportError(pos, "unexpected character '"+ch+"', expected some markupdecl") + while (ch!='>') + nextch } } } def markupDecl(): Unit = ch match { case '%' => // parameter entity reference - nextch; - val ent = xName; - xToken(';'); - if(!isValidating) - handle.peReference(ent); // n-v: just create PE-reference + nextch + val ent = xName + xToken(';') + if (!isValidating) + handle.peReference(ent) // n-v: just create PE-reference else - push(ent); // v: parse replacementText + push(ent) // v: parse replacementText //peReference case '<' => - nextch; - markupDecl1(); - + nextch + markupDecl1() case _ if isSpace(ch) => - xSpace; + xSpace case _ => - reportSyntaxError("markupdecl: unexpected character '"+ch+"' #" + ch.asInstanceOf[Int]); - nextch; + reportSyntaxError("markupdecl: unexpected character '"+ch+"' #" + ch.asInstanceOf[Int]) + nextch } /** "rec-xml/#ExtSubset" pe references may not occur within markup declarations */ def intSubset(): Unit = { - //Console.println("(DEBUG) intSubset()"); - xSpace; - while (']' != ch) { + //Console.println("(DEBUG) intSubset()") + xSpace + while (']' != ch) markupDecl() - } } /** <! element := ELEMENT */ def elementDecl(): Unit = { - xToken("EMENT"); - xSpace; - val n = xName; - xSpace; + xToken("EMENT") + xSpace + val n = xName + xSpace while ('>' != ch) { - //Console.println("["+ch+"]"); - putChar(ch); - nextch; + //Console.println("["+ch+"]") + putChar(ch) + nextch } - //Console.println("END["+ch+"]"); - nextch; - val cmstr = cbuf.toString(); - cbuf.setLength(0); - handle.elemDecl(n, cmstr); + //Console.println("END["+ch+"]") + nextch + val cmstr = cbuf.toString() + cbuf.setLength(0) + handle.elemDecl(n, cmstr) } /** <! attlist := ATTLIST */ def attrDecl() = { - xToken("TTLIST"); - xSpace; - val n = xName; - xSpace; - var attList: List[AttrDecl] = Nil; + xToken("TTLIST") + xSpace + val n = xName + xSpace + var attList: List[AttrDecl] = Nil // later: find the elemDecl for n while ('>' != ch) { - val aname = xName; + val aname = xName //Console.println("attribute name: "+aname); - var defdecl: DefaultDecl = null; - xSpace; + var defdecl: DefaultDecl = null + xSpace // could be enumeration (foo,bar) parse this later :-/ while ('"' != ch && '\'' != ch && '#' != ch && '<' != ch) { - if(!isSpace(ch)) + if (!isSpace(ch)) cbuf.append(ch); nextch; } - val atpe = cbuf.toString(); - cbuf.setLength(0); + val atpe = cbuf.toString() + cbuf.setLength(0) //Console.println("attr type: "+atpe); ch match { case '\'' | '"' => - val defValue = xAttributeValue(); // default value - defdecl = DEFAULT(false, defValue); + val defValue = xAttributeValue() // default value + defdecl = DEFAULT(false, defValue) case '#' => - nextch; + nextch xName match { case "FIXED" => - xSpace; - val defValue = xAttributeValue(); // default value - defdecl = DEFAULT(true, defValue); + xSpace + val defValue = xAttributeValue() // default value + defdecl = DEFAULT(true, defValue) case "IMPLIED" => defdecl = IMPLIED case "REQUIRED" => @@ -1026,85 +1018,81 @@ trait MarkupParser requires (MarkupParser with MarkupHandler) extends AnyRef wit } case _ => } - xSpaceOpt; + xSpaceOpt - attList = AttrDecl(aname, atpe, defdecl) :: attList; - cbuf.setLength(0); + attList = AttrDecl(aname, atpe, defdecl) :: attList + cbuf.setLength(0) } - nextch; - handle.attListDecl(n, attList.reverse); + nextch + handle.attListDecl(n, attList.reverse) } /** <! element := ELEMENT */ def entityDecl() = { - //Console.println("entityDecl()"); - var isParameterEntity = false; - var entdef: EntityDef = null; - xToken("NTITY"); - xSpace; + //Console.println("entityDecl()") + var isParameterEntity = false + var entdef: EntityDef = null + xToken("NTITY") + xSpace if ('%' == ch) { - nextch; - isParameterEntity = true; - xSpace; + nextch + isParameterEntity = true + xSpace } - val n = xName; - xSpace; + val n = xName + xSpace ch match { case 'S' | 'P' => //sy - val extID = externalID(); - if(isParameterEntity) { - - xSpaceOpt; - xToken('>'); + val extID = externalID() + if (isParameterEntity) { + xSpaceOpt + xToken('>') handle.parameterEntityDecl(n, ExtDef(extID)) - } else { // notation? - - xSpace; + xSpace if ('>' != ch) { - xToken("NDATA"); - xSpace; - val notat = xName; - xSpaceOpt; - xToken('>'); - handle.unparsedEntityDecl(n, extID, notat); + xToken("NDATA") + xSpace + val notat = xName + xSpaceOpt + xToken('>') + handle.unparsedEntityDecl(n, extID, notat) } else { - nextch; - handle.parsedEntityDecl(n, ExtDef(extID)); + nextch + handle.parsedEntityDecl(n, ExtDef(extID)) } } case '"' | '\'' => - val av = xEntityValue(); - xSpaceOpt; - xToken('>'); + val av = xEntityValue() + xSpaceOpt + xToken('>') if (isParameterEntity) - handle.parameterEntityDecl(n, IntDef(av)); + handle.parameterEntityDecl(n, IntDef(av)) else - handle.parsedEntityDecl(n, IntDef(av)); + handle.parsedEntityDecl(n, IntDef(av)) } - {} } // entityDecl /** 'N' notationDecl ::= "OTATION" */ def notationDecl(): Unit = { - xToken("OTATION"); - xSpace; - val notat = xName; - xSpace; + xToken("OTATION") + xSpace + val notat = xName + xSpace val extID = if (ch == 'S') { externalID(); } else if (ch == 'P') { /** PublicID (without system, only used in NOTATION) */ - nextch; - xToken("UBLIC"); - xSpace; - val pubID = pubidLiteral(); - xSpaceOpt; + nextch + xToken("UBLIC") + xSpace + val pubID = pubidLiteral() + xSpaceOpt val sysID = if (ch != '>') systemLiteral() else @@ -1112,8 +1100,8 @@ trait MarkupParser requires (MarkupParser with MarkupHandler) extends AnyRef wit new PublicID(pubID, sysID); } else error("PUBLIC or SYSTEM expected"); - xSpaceOpt; - xToken('>'); + xSpaceOpt + xToken('>') handle.notationDecl(notat, extID) } @@ -1121,60 +1109,58 @@ trait MarkupParser requires (MarkupParser with MarkupHandler) extends AnyRef wit * report a syntax error */ def reportSyntaxError(pos: int, str: String): Unit = { - curInput.reportError(pos, str); - //error("MarkupParser::synerr"); // DEBUG + curInput.reportError(pos, str) + //error("MarkupParser::synerr") // DEBUG } - def reportSyntaxError(str: String): Unit = reportSyntaxError(pos, str); + def reportSyntaxError(str: String): Unit = reportSyntaxError(pos, str) /** * report a syntax error */ - def reportValidationError(pos: int, str: String): Unit = { + def reportValidationError(pos: int, str: String): Unit = curInput.reportError(pos, str) - } - def push(entityName:String) = { - //Console.println("BEFORE PUSHING "+ch); - //Console.println("BEFORE PUSHING "+pos); - //Console.print("[PUSHING "+entityName+"]"); - if(!eof) - inpStack = curInput :: inpStack; - - curInput = replacementText(entityName); - nextch; + //Console.println("BEFORE PUSHING "+ch) + //Console.println("BEFORE PUSHING "+pos) + //Console.print("[PUSHING "+entityName+"]") + if (!eof) + inpStack = curInput :: inpStack + + curInput = replacementText(entityName) + nextch } /* def push(src:Source) = { - curInput = src; - nextch; + curInput = src + nextch } */ def pushExternal(systemId:String) = { - //Console.print("BEFORE PUSH, curInput = $"+curInput.descr); - //Console.println(" stack = "+inpStack.map { x => "$"+x.descr }); + //Console.print("BEFORE PUSH, curInput = $"+curInput.descr) + //Console.println(" stack = "+inpStack.map { x => "$"+x.descr }) - //Console.print("[PUSHING EXTERNAL "+systemId+"]"); - if(!eof) - inpStack = curInput :: inpStack; + //Console.print("[PUSHING EXTERNAL "+systemId+"]") + if (!eof) + inpStack = curInput :: inpStack - curInput = externalSource(systemId); + curInput = externalSource(systemId) - //Console.print("AFTER PUSH, curInput = $"+curInput.descr); - //Console.println(" stack = "+inpStack.map { x => "$"+x.descr }); + //Console.print("AFTER PUSH, curInput = $"+curInput.descr) + //Console.println(" stack = "+inpStack.map { x => "$"+x.descr }) - nextch; + nextch } - def pop() = { - curInput = inpStack.head; - inpStack = inpStack.tail; - ch = curInput.ch; - pos = curInput.pos; - eof = false; // must be false, because of places where entity refs occur + def pop() = { + curInput = inpStack.head + inpStack = inpStack.tail + ch = curInput.ch + pos = curInput.pos + eof = false // must be false, because of places where entity refs occur //Console.println("\n AFTER POP, curInput = $"+curInput.descr); //Console.println(inpStack.map { x => x.descr }); } @@ -1184,41 +1170,41 @@ trait MarkupParser requires (MarkupParser with MarkupHandler) extends AnyRef wit * precond: cbuf empty */ def normalizeAttributeValue(attval: String) = { - val s:Seq[Char] = attval; - val it = s.elements; + val s: Seq[Char] = attval + val it = s.elements while(it.hasNext) { it.next match { case ' '|'\t'|'\n'|'\r' => cbuf.append(' '); case '&' => it.next match { case '#' => - var c = it.next; - val s = xCharRef ({ () => c }, { () => c = it.next }); - cbuf.append(s); + var c = it.next + val s = xCharRef ({ () => c }, { () => c = it.next }) + cbuf.append(s) case nchar => - val nbuf = new StringBuilder(); - var d = nchar; + val nbuf = new StringBuilder() + var d = nchar do { - nbuf.append(d); - d = it.next; + nbuf.append(d) + d = it.next } while(d != ';'); nbuf.toString() match { - case "lt" => cbuf.append('<'); - case "gt" => cbuf.append('>'); - case "amp" => cbuf.append('&'); - case "quote" => cbuf.append('"'); + case "lt" => cbuf.append('<') + case "gt" => cbuf.append('>') + case "amp" => cbuf.append('&') + case "quote" => cbuf.append('"') case name => //don't handle entityrefs for now - cbuf.append('&'); - cbuf.append(name); - cbuf.append(';'); + cbuf.append('&') + cbuf.append(name) + cbuf.append(';') } } - case c => cbuf.append(c); + case c => cbuf.append(c) } } - val name = cbuf.toString(); - cbuf.setLength(0); + val name = cbuf.toString() + cbuf.setLength(0) name } diff --git a/src/library/scala/xml/transform/BasicTransformer.scala b/src/library/scala/xml/transform/BasicTransformer.scala index cf32b1e472..ca9cd70a9d 100644 --- a/src/library/scala/xml/transform/BasicTransformer.scala +++ b/src/library/scala/xml/transform/BasicTransformer.scala @@ -8,75 +8,83 @@ // $Id$ +package scala.xml.transform -package scala.xml.transform; - - -/** a class for XML transformations */ +/** A class for XML transformations. + * + * @author Burak Emir + * @version 1.0 + */ abstract class BasicTransformer extends Function1[Node,Node] { - protected case class NeedsCopy(result:Seq[Node]) extends java.lang.Throwable; + protected case class NeedsCopy(result: Seq[Node]) extends java.lang.Throwable - /** returns a new node buffer with the first pos elements from ns */ - protected def buffer(pos:Int, ns:Seq[Node]): NodeBuffer = { - val nb = new NodeBuffer(); - var jt = ns.elements; - var j = 0; while( j < pos-1 ) { - nb.append(jt.next); - j = j + 1; + /** Returns a new node buffer with the first <code>pos</code> elements + * from <code>ns</code>. + */ + protected def buffer(pos: Int, ns :Seq[Node]): NodeBuffer = { + val nb = new NodeBuffer() + var jt = ns.elements + var j = 0; while (j < pos-1) { + nb.append(jt.next) + j = j + 1 } nb } /** turns a nodebuffer into a sequence, so hashcode works */ - protected def freeze(nb:NodeBuffer):Seq[Node] = { - val arr = new Array[Node](nb.length); - var i = 0; - val it = nb.elements; while( it.hasNext ) { - arr(i) = it.next; - i = i + 1; + protected def freeze(nb: NodeBuffer): Seq[Node] = { + val arr = new Array[Node](nb.length) + var i = 0 + val it = nb.elements; while (it.hasNext) { + arr(i) = it.next + i = i + 1 } - val seq: Seq[Node] = arr; + val seq: Seq[Node] = arr seq } - protected def single(ns:Seq[Node]) = { - (1 == ns.length) - } - protected def unchanged(n:Node, ns:Seq[Node]) = { + protected def single(ns: Seq[Node]) = + 1 == ns.length + + /** + * @param n ... + * @param ns ... + * @return ... + */ + protected def unchanged(n: Node, ns: Seq[Node]) = single(ns) && (ns.elements.next.eq(n)) - } - /** call transform(Node) for each node in ns, append results - * to NodeBuffer */ - def transform(it: Iterator[Node], nb:NodeBuffer): Seq[Node] = { - while( it.hasNext ) - nb ++ transform( it.next ); - freeze(nb); + /** Call transform(Node) for each node in ns, append results + * to NodeBuffer. + */ + def transform(it: Iterator[Node], nb: NodeBuffer): Seq[Node] = { + while (it.hasNext) + nb ++ transform(it.next); + freeze(nb) } - /** - * call transform(Node) to each node in ns, yield ns if nothing changes, - * otherwise a new sequence of concatenated results + /** Call transform(Node) to each node in ns, yield ns if nothing changes, + * otherwise a new sequence of concatenated results. */ def transform(ns: Seq[Node]): Seq[Node] = { - var i = 0; - val it = ns.elements; + var i = 0 + val it = ns.elements try { - while( it.hasNext ) { - val n = it.next; - val n2 = transform(n); - if(!unchanged(n,n2)) { - throw NeedsCopy(n2) - } - i = i + 1; + while (it.hasNext) { + val n = it.next + val n2 = transform(n) + if (!unchanged(n, n2)) { + throw NeedsCopy(n2) + } + i = i + 1 } ns } catch { case NeedsCopy(n2) => - val nb = buffer(i, ns); - nb ++ n2; - transform(it, nb); + val nb = buffer(i, ns) + nb ++ n2 + transform(it, nb) } } @@ -84,20 +92,20 @@ abstract class BasicTransformer extends Function1[Node,Node] { if (n.typeTag$ < 0) n else { - val ch = n.child; - val nch = transform(ch); - if(ch.eq(nch)) - n + val ch = n.child + val nch = transform(ch) + if (ch.eq(nch)) + n else - Elem(n.prefix, n.label, n.attributes, n.scope, nch:_*) + Elem(n.prefix, n.label, n.attributes, n.scope, nch:_*) } } def apply(n: Node): Node = { - val seq = transform(n); - if( !single(seq) ) + val seq = transform(n) + if (!single(seq)) error("transform must return single node for root"); - else seq.elements.next; + else seq.elements.next } } diff --git a/src/library/scala/xml/transform/RewriteRule.scala b/src/library/scala/xml/transform/RewriteRule.scala index 33a7e47ea9..8100e6eae9 100644 --- a/src/library/scala/xml/transform/RewriteRule.scala +++ b/src/library/scala/xml/transform/RewriteRule.scala @@ -8,18 +8,19 @@ // $Id$ - -package scala.xml.transform; - +package scala.xml.transform /** a RewriteRule, when applied to a term, yields either * the resulting of rewriting or the term itself it the rule - * is not applied + * is not applied. + * + * @author Burak Emir + * @version 1.0 */ abstract class RewriteRule extends BasicTransformer { /** a name for this rewrite rule */ - val name = this.toString(); - override def transform(ns:Seq[Node]): Seq[Node] = super.transform(ns); - override def transform(n:Node): Seq[Node] = n; + val name = this.toString() + override def transform(ns: Seq[Node]): Seq[Node] = super.transform(ns) + override def transform(n: Node): Seq[Node] = n } |