summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorburaq <buraq@epfl.ch>2005-04-24 22:19:29 +0000
committerburaq <buraq@epfl.ch>2005-04-24 22:19:29 +0000
commit67290d08794a237841dca5cfcb3fda7c05d22cdf (patch)
treed8cbdc226b49d80b18d0f6106fb2a5969fcacbe8
parent6d081b3c4c6647386bd1b113e50d6285ff81aa99 (diff)
downloadscala-67290d08794a237841dca5cfcb3fda7c05d22cdf.tar.gz
scala-67290d08794a237841dca5cfcb3fda7c05d22cdf.tar.bz2
scala-67290d08794a237841dca5cfcb3fda7c05d22cdf.zip
rearrangement of Scala XML library
-rw-r--r--config/list/library.lst14
-rw-r--r--sources/scala/xml/Comment.scala20
-rw-r--r--sources/scala/xml/Elem.scala5
-rw-r--r--sources/scala/xml/EntityRef.scala25
-rw-r--r--sources/scala/xml/FactoryAdapter.scala345
-rw-r--r--sources/scala/xml/LoggedNodeFactory.scala78
-rw-r--r--sources/scala/xml/Node.scala14
-rw-r--r--sources/scala/xml/NodeFactory.scala77
-rw-r--r--sources/scala/xml/ProcInstr.scala33
-rw-r--r--sources/scala/xml/SpecialNode.scala13
-rw-r--r--sources/scala/xml/Text.scala16
-rw-r--r--sources/scala/xml/Utility.scala97
-rw-r--r--sources/scala/xml/nobinding/NoBindingFactoryAdapter.scala61
-rw-r--r--sources/scala/xml/nobinding/XML.scala76
-rw-r--r--test/files/jvm/xml01.scala112
-rw-r--r--test/files/jvm/xmlstuff.scala3
16 files changed, 167 insertions, 822 deletions
diff --git a/config/list/library.lst b/config/list/library.lst
index 2c32d8662f..4412243468 100644
--- a/config/list/library.lst
+++ b/config/list/library.lst
@@ -215,17 +215,12 @@ util/logging/Logged.scala
util/logging/ConsoleLogger.scala
xml/Comment.scala
-xml/DocType.scala
xml/Elem.scala
xml/EntityRef.scala
-xml/ExternalID.scala
-xml/FactoryAdapter.scala
-xml/LoggedNodeFactory.scala
xml/MetaData.scala
xml/NamespaceBinding.scala
xml/Node.scala
xml/NodeBuffer.scala
-xml/NodeFactory.scala
xml/NodeSeq.scala
#xml/NodeTraverser.scala
xml/Null.scala
@@ -239,23 +234,28 @@ xml/TextBuffer.scala
xml/TopScope.scala
xml/UnprefixedAttribute.scala
xml/Utility.scala
+xml/XML.scala
xml/dtd/ContentModel.scala
+xml/dtd/DocType.scala
xml/dtd/Decl.scala
+xml/dtd/ExternalID.scala
xml/dtd/Parser.scala
xml/dtd/Scanner.scala
xml/dtd/Tokens.scala
xml/dtd/Validation.scala
xml/dtd/ValidationException.scala
-xml/nobinding/NoBindingFactoryAdapter.scala
-xml/nobinding/XML.scala
+xml/factory/NodeFactory.scala
+xml/factory/LoggedNodeFactory.scala
xml/parsing/ConstructingHandler.scala
xml/parsing/ConstructingParser.scala
xml/parsing/FatalError.scala
xml/parsing/MarkupHandler.scala
xml/parsing/MarkupParser.scala
+xml/parsing/FactoryAdapter.scala
+xml/parsing/NoBindingFactoryAdapter.scala
xml/path/Expression.scala
xml/transform/BasicTransformer.scala
diff --git a/sources/scala/xml/Comment.scala b/sources/scala/xml/Comment.scala
index 2b646ad001..d075fdad77 100644
--- a/sources/scala/xml/Comment.scala
+++ b/sources/scala/xml/Comment.scala
@@ -15,27 +15,29 @@ import scala.collection.immutable ;
*
* @author Burak Emir
* @param text text contained in this node, may not contain "--"
-**/
+ */
-case class Comment( text:String ) extends SpecialNode {
+case class Comment(text: String) extends SpecialNode {
final override def typeTag$:Int = -3;
if( text.indexOf("--" ) != -1 )
throw new IllegalArgumentException("text containts \"--\"");
- final override def equals(x:Any) = x match {
- case Comment( s ) => text.equals( s );
- case _ => false;
+ /** structural equality */
+ override def equals(x: Any): Boolean = x match {
+ case Comment(x) => x.equals(text);
+ case _ => false
}
- /** the constant "#REM" */
+ /** the constant &quot;#REM&quot; */
def label = "#REM";
/** hashcode for this Comment */
override def hashCode() = text.hashCode();
- /** returns "<!--"+text+"-->" */
- final override def toString() = "<!--"+text+"-->";
-
+ /** appends &quot;<!-- text -->&quot; to this stringbuffer */
+ def toString(sb: StringBuffer) = {
+ sb.append("<!--").append(text).append("-->")
+ }
}
diff --git a/sources/scala/xml/Elem.scala b/sources/scala/xml/Elem.scala
index 747f0d5757..d4dc0c8ab9 100644
--- a/sources/scala/xml/Elem.scala
+++ b/sources/scala/xml/Elem.scala
@@ -23,7 +23,10 @@ import scala.collection.mutable.ArrayBuffer;
// "val" is redundant for non-overriding arguments
case class Elem(override val prefix:String, val label: String, override val attributes: MetaData, override val scope: NamespaceBinding, val child: Node*) extends Node {
- if(null== scope)
+ if(prefix != null && 0 == prefix.length())
+ error("prefix of zero length, use null instead");
+
+ if(null == scope)
error("scope is null");
//@todo: copy the children,
diff --git a/sources/scala/xml/EntityRef.scala b/sources/scala/xml/EntityRef.scala
index a3de453c30..192cf85797 100644
--- a/sources/scala/xml/EntityRef.scala
+++ b/sources/scala/xml/EntityRef.scala
@@ -9,29 +9,30 @@
package scala.xml;
-import scala.collection.immutable ;
-/** an XML node for text (PCDATA). Used in both non-bound and bound XML
- * representations
- * @author Burak Emir
+/** an XML node for entity references
+ *
+ * @author buraq
* @param text the text contained in this node
-**/
+ **/
case class EntityRef( entityName:String ) extends SpecialNode {
final override def typeTag$:Int = -5;
+ /** structural equality */
+ override def equals(x: Any): Boolean = x match {
+ case EntityRef(x) => x.equals(entityName);
+ case _ => false
+ }
+
/** the constant "#ENTITY"
*/
def label = "#ENTITY";
- final override def equals(x:Any) = x match {
- case EntityRef( s ) => entityName.equals( s );
- case _ => false;
- }
-
override def hashCode() = entityName.hashCode();
- /** returns text, with some characters escaped according to XML spec */
- final override def toString():String = "&"+entityName+";";
+ /** appends "&amp; entityName;" to this stringbuffer */
+ def toString(sb:StringBuffer) =
+ sb.append("&").append(entityName).append(";");
}
diff --git a/sources/scala/xml/FactoryAdapter.scala b/sources/scala/xml/FactoryAdapter.scala
deleted file mode 100644
index e120811269..0000000000
--- a/sources/scala/xml/FactoryAdapter.scala
+++ /dev/null
@@ -1,345 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2004, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-** $Id$
-\* */
-package scala.xml ;
-
-import java.io._ ;
-import scala.collection.mutable.{HashMap,Stack};
-
-import org.xml.sax.Attributes;
-import org.xml.sax.ContentHandler;
-
-
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.Locator;
-import org.xml.sax.InputSource;
-
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXNotRecognizedException;
-import org.xml.sax.SAXNotSupportedException;
-import org.xml.sax.SAXParseException;
-import org.xml.sax.helpers.DefaultHandler;
-
-import javax.xml.parsers.SAXParserFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.SAXParser;
-
-
-/** SAX adapter class, for use with Java SAX parser. Keeps track of
- * namespace bindings, without relying on namespace handling of the
- * underlying SAX parser.
- */
-abstract class FactoryAdapter extends DefaultHandler() {
-
- val buffer = new StringBuffer();
- val attribStack = new Stack[MetaData];
- val hStack = new Stack[Node]; // [ element ] contains siblings
- val tagStack = new Stack[String];
- var scopeStack = new Stack[NamespaceBinding];
-
- var curTag : String = null ;
- var capture:boolean = false;
-
- // abstract methods
-
- /** Tests if an XML element contains text.
- * @return true if element named <code>localName</code> contains text.
- */
- def nodeContainsText( localName:String ):boolean ; // abstract
-
- /** creates an new non-text(tree) node.
- * @param elemName
- * @param attribs
- * @param chIter
- * @return a new XML element.
- */
- def createNode(pre: String, elemName: String, attribs: MetaData, scope: NamespaceBinding, chIter: List[Node] ):Node; //abstract
-
- /** creates a Text node.
- * @param text
- * @return a new Text node.
- */
- def createText( text:String ):Text[String]; // abstract
-
- //
- // ContentHandler methods
- //
-
- val normalizeWhitespace = false;
-
- /** Characters.
- * @param ch
- * @param offset
- * @param length
- */
- override def characters(ch: Array[Char], offset: Int, length: Int): Unit = {
-
- if (capture) {
- if( normalizeWhitespace ) { // normalizing whitespace is not compliant, but useful */
- var i:int = offset;
- var ws:boolean = false;
- while (i < offset + length) {
- if ( Character.isWhitespace( ch(i) ) ) {
- if (!ws) {
- buffer.append(' ');
- ws = true;
- }
- } else {
- buffer.append(ch(i));
- ws = false;
- }
- i = i+1;
- }
- } else { // compliant:report every character
-
- buffer.append( ch, offset, length );
-
- }
- }
- }
-
- //var elemCount = 0; //STATISTICS
-
- /* ContentHandler methods */
-
- /* Start prefix mapping - use default impl.
- def startPrefixMapping( prefix:String , uri:String ):Unit = {}
- */
-
-
-
- /* Start element. */
- override def startElement(uri:String, _localName:String, qname:String, attributes:Attributes ):Unit = {
- /*elemCount = elemCount + 1; STATISTICS */
- captureText();
- //Console.println("FactoryAdapter::startElement("+uri+","+_localName+","+qname+","+attributes+")");
- tagStack.push(curTag);
- curTag = qname; //localName ;
-
- val colon = qname.indexOf(':');
- val localName = if(-1 == colon) qname else qname.substring(colon+1,qname.length());
-
- //Console.println("FactoryAdapter::startElement - localName ="+localName);
-
- capture = nodeContainsText(localName) ;
-
- hStack.push( null );
- var m: MetaData = Null;
-
- var scpe = scopeStack.top;
- for( val i <- List.range( 0, attributes.getLength() )) {
- //val attrType = attributes.getType(i); // unused for now
- val qname = attributes.getQName(i);
- val value = attributes.getValue(i);
- val colon = qname.indexOf(':');
- if(-1 != colon) { // prefixed attribute
- val pre = qname.substring(0, colon);
- val key = qname.substring(colon+1, qname.length());
- if("xmlns" == pre)
- scpe = value.length() match {
- case 0 => new NamespaceBinding(key, null, scpe);
- case _ => new NamespaceBinding(key, value, scpe);
- }
- else
- m = new PrefixedAttribute(pre, key, value, m)
- } else if("xmlns" == qname)
- scpe = value.length() match {
- case 0 => new NamespaceBinding(null, null, scpe);
- case _ => new NamespaceBinding(null, value, scpe);
- }
- else
- m = new UnprefixedAttribute(qname, value, m)
- }
- scopeStack.push(scpe);
- attribStack.push( m );
- {}
- } // startElement(String,String,String,Attributes)
-
-
- /** captures text, possibly normalizing whitespace
- */
- def captureText():Unit = {
- if (capture == true) {
- val text = buffer.toString();
- if(( text.length() > 0 )&&( !( text.equals(" ")))) {
- val _ = hStack.push( createText( text ) );
- }
- }
- buffer.setLength(0);
- }
-
- /** End element.
- * @param uri
- * @param localName
- * @param qname
- * @throws org.xml.sax.SAXException if ..
- */
- override def endElement(uri:String , _localName:String , qname:String ):Unit = {
- captureText();
-
- val metaData = attribStack.pop;
-
- // reverse order to get it right
- var v:List[Node] = Nil;
- var child:Node = hStack.pop;
- while( child != null ) {
- v = child::v;
- child = hStack.pop;
- }
-
- val colon = qname.indexOf(':');
- val localName = if(-1 == colon) qname else qname.substring(colon+1,qname.length());
-
- val scp = scopeStack.pop;
- // create element
- rootElem = if(-1 == colon)
- createNode( null, localName, metaData, scp, v );
- else
- createNode( qname.substring(0,colon), localName, metaData, scp, v );
-
- hStack.push(rootElem);
-
- // set
- curTag = tagStack.pop;
-
- if (curTag != null) // root level
- capture = nodeContainsText(curTag);
- else
- capture = false;
-
- } // endElement(String,String,String)
-
- //
- // ErrorHandler methods
- //
-
- /** Warning.*/
- override def warning(ex:SAXParseException ):Unit = {
- // ignore warning, crimson warns even for entity resolution!
- //printError("Warning", ex);
- }
- /** Error. */
- override def error(ex:SAXParseException ):Unit = {
- printError("Error", ex);
- }
-
- /** Fatal error.*/
- override def fatalError(ex:SAXParseException ):Unit = {
- printError("Fatal Error", ex);
- }
-
- //
- // Protected methods
- //
-
- /** Prints the error message */
- protected def printError( errtype:String , ex:SAXParseException ):Unit = {
-
- System.err.print("[");
- System.err.print(errtype);
- System.err.print("] ");
-
- var systemId = ex.getSystemId();
- if (systemId != null) {
- val index = systemId.lastIndexOf('/');
- if (index != -1)
- systemId = systemId.substring(index + 1);
- //System.err.print(systemId);
- }
-
- System.err.print(':');
- System.err.print(ex.getLineNumber());
- System.err.print(':');
- System.err.print(ex.getColumnNumber());
- System.err.print(": ");
- System.err.print(ex.getMessage());
- System.err.println();
- System.err.flush();
-
- }
-
- var rootElem : Node = null:Node;
-
- //FactoryAdapter
- // MAIN
- //
-
- /** load XML document
- * @param source
- * @return a new XML document object
- */
- def loadXML( source:InputSource ):Node = {
-
- // variables
- var parser:SAXParser = null;
-
- // create parser
- try {
- val f = SAXParserFactory.newInstance();
- f.setNamespaceAware( false );
- parser = f.newSAXParser();
- } catch {
- case ( e:Exception ) => {
- System.err.println("error: Unable to instantiate parser");
- System.exit(-1);
- }
- }
-
- // parse file
- try {
- //System.err.println("[parsing \"" + source + "\"]");
- scopeStack.push(TopScope);
- parser.parse( source, this );
- scopeStack.pop;
- } catch {
- case ( e:SAXParseException ) => {
- // ignore
- }
- case ( e:Exception ) => {
- System.err.println("error: Parse error occurred - " + e.getMessage());
- if (e.isInstanceOf[ SAXException ]) {
- (e.asInstanceOf[ SAXException ])
- .getException()
- .printStackTrace( System.err );
- } else {
- e.printStackTrace(System.err);
- }
- }
- } // catch
- //System.err.println("[FactoryAdapter: total #elements = "+elemCount+"]");
- rootElem
-
- } // loadXML
-
-
-
- /** loads XML from given file */
- def loadFile( file:File ):Node = loadXML( new InputSource(
- new FileInputStream( file )
- ));
-
- /** loads XML from given file descriptor */
- def loadFile( fileDesc:FileDescriptor ):Node = loadXML( new InputSource(
- new FileInputStream( fileDesc )
- ));
-
- /** loads XML from given file */
- def loadFile( fileName:String ):Node = loadXML( new InputSource(
- new FileInputStream( fileName )
- ));
-
- /** loads XML from given InputStream */
- def load( is:InputStream ):Node = loadXML( new InputSource( is ));
-
- /** loads XML from given Reader */
- def load( reader:Reader ):Node = loadXML( new InputSource( reader ));
-
- /** loads XML from given sysID */
- def load( sysID:String ):Node = loadXML( new InputSource( sysID ));
-
-}
diff --git a/sources/scala/xml/LoggedNodeFactory.scala b/sources/scala/xml/LoggedNodeFactory.scala
deleted file mode 100644
index e838b1b56c..0000000000
--- a/sources/scala/xml/LoggedNodeFactory.scala
+++ /dev/null
@@ -1,78 +0,0 @@
-package scala.xml;
-
-/** This class logs what the nodefactory is actually doing.
-If you want to see what happens during loading, use it like this:
-object testLogged with Application {
-
- val x = new scala.xml.nobinding.NoBindingFactoryAdapter
- with scala.xml.LoggedNodeFactory[scala.xml.Elem]()
- with scala.util.logging.ConsoleLogger;
-
- Console.println("Start");
-
- val doc = x.loadXML(new org.xml.sax.InputSource("http://lamp.epfl.ch/~buraq"));
-
- Console.println("End");
-
- Console.println(doc);
-}
-
-*/
-abstract class LoggedNodeFactory[A <: Node]
-extends NodeFactory[A]
-with scala.util.logging.Logged {
-
- // configuration values;
- val logNode = true;
- val logText = false;
- val logComment = false;
- val logProcInstr = false;
-
- final val NONE = 0;
- final val CACHE = 1;
- final val FULL = 2;
- /** 0 = no loggging, 1 = cache hits, 2 = detail */
- val logCompressLevel = 1;
-
- // methods of NodeFactory
-
- /** logged version of makeNode method */
- override def makeNode(pre:String, label:String, attrSeq:MetaData, scope: NamespaceBinding, children:Seq[Node]): A = {
- if(logNode)
- log("[makeNode for "+label+"]");
-
- val hash = Utility.hashCode(pre, label, attrSeq.hashCode(), scope.hashCode(), children) ;
-
- /*
- if(logCompressLevel >= FULL) {
- log("[hashcode total:"+hash);
- log(" elem name "+uname+" hash "+ ? ));
- log(" attrs "+attrSeq+" hash "+attrSeq.hashCode());
- log(" children :"+children+" hash "+children.hashCode());
- }
- */
- if(!cache.get( hash ).isEmpty && (logCompressLevel >= CACHE))
- log("[cache hit !]");
-
- super.makeNode(pre, label, attrSeq, scope, children);
- }
-
- override def makeText(s: String) = {
- if(logText)
- log("[makeText:\""+s+"\"]");
- super.makeText( s );
- }
-
- override def makeComment(s: String): Seq[Comment] = {
- if(logComment)
- log("[makeComment:\""+s+"\"]");
- super.makeComment( s );
- }
-
- override def makeProcInstr(t: String, s: String): Seq[ProcInstr] = {
- if(logProcInstr)
- log("[makeProcInstr:\""+t+" "+ s+"\"]");
- super.makeProcInstr(t,s);
- }
-
-}
diff --git a/sources/scala/xml/Node.scala b/sources/scala/xml/Node.scala
index 7f73bc4260..58158eca9f 100644
--- a/sources/scala/xml/Node.scala
+++ b/sources/scala/xml/Node.scala
@@ -34,9 +34,6 @@ abstract class Node extends NodeSeq {
/** label of this node. I.e. "foo" for &lt;foo/&gt;) */
def label: String;
- /** the namespace of this node */
- //final def namespace: String = scope.getURI(prefix);
-
/** used internally. Text = -1 PI = -2 Comment = -3 EntityRef = -5 */
def typeTag$: Int = 0;
@@ -76,17 +73,16 @@ abstract class Node extends NodeSeq {
def descendant_or_self: List[Node] = this :: descendant;
/** structural equality */
- override def equals(x: Any): Boolean = {
- x match {
+ override def equals(x: Any): Boolean = x match {
case that: Node =>
- (that.label == this.label )
+ (that.prefix == this.prefix )
+ &&(that.label == this.label )
&&(that.attributes == this.attributes)
- && that.child.sameElements(this.child)// sameElements
+ && that.child.sameElements(this.child) // sameElements
case _ => false
- }
}
/** returns a hashcode */
- override def hashCode(): Int = 0;
+ override def hashCode(): Int;
//Utility.hashCode(namespace, label, attributes.hashCode(), child);
diff --git a/sources/scala/xml/NodeFactory.scala b/sources/scala/xml/NodeFactory.scala
deleted file mode 100644
index c22ff2babd..0000000000
--- a/sources/scala/xml/NodeFactory.scala
+++ /dev/null
@@ -1,77 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2004, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-** $Id $
-\* */
-
-package scala.xml;
-
-import scala.collection.Map ;
-import scala.collection.mutable ;
-
-abstract class NodeFactory[A <: Node] {
-
- val ignoreComments = false;
- val ignoreProcInstr = false;
-
- /* default behaviour is to use hash-consing */
- val cache = new mutable.HashMap[int,List[A]]();
-
- protected def create(pre: String, name: String, attrs: MetaData, scope: NamespaceBinding, children:Seq[Node]): A;
-
- protected def construct(hash:Int, old:List[A], pre: String, name: String, attrSeq:MetaData, scope: NamespaceBinding, children:Seq[Node]): A = {
- val el = create(pre, name, attrSeq, scope, children);
- cache.update( hash, el::old );
- el
- }
-
- /** faster equality, because */
- def eqElements(ch1:Seq[Node], ch2:Seq[Node]): Boolean = {
- (ch1.length == ch2.length) && {
- val it1 = ch1.elements;
- val it2 = ch2.elements;
- var res = true;
- while(res && it1.hasNext) {
- res = it1.next.eq(it2.next);
- }
- res
- }
- }
-
- def nodeEquals(n: Node, pre: String, name: String, attrSeq:MetaData, scope: NamespaceBinding, children:Seq[Node]) =
- (n.prefix == pre)
- &&(n.label == name)
- &&(n.attributes == attrSeq)
- // scope??
- &&(eqElements(n.child,children));
-
- def makeNode(pre: String, name: String, attrSeq:MetaData, scpe: NamespaceBinding, children:Seq[Node]): A = {
- //Console.println("NodeFactory::makeNode("+pre+","+name+","+attrSeq+","+scpe+","+children+")");
- val hash = Utility.hashCode( pre, name, attrSeq.hashCode(), scpe.hashCode(), children ) ;
- cache.get( hash ) match {
- case Some(list) => // find structurally equal
- val it = list.elements;
- val lookup = it.find { x => nodeEquals(x, pre, name, attrSeq, scpe, children) };
- lookup match {
- case Some(x) =>
- //Console.println("[cache hit !]"+x);
- x; // return cached elem
- case _ => construct(hash, list, pre, name, attrSeq, scpe, children);
- }
- case _ => construct(hash, Nil, pre, name, attrSeq, scpe, children)
- }
- }
-
- def makeText(s: String) =
- Text( s );
-
- def makeComment(s: String): Seq[Comment] =
- if(ignoreComments) Nil else List(Comment( s ));
-
- def makeProcInstr(t: String, s: String): Seq[ProcInstr] =
- if(ignoreProcInstr) Nil else List(ProcInstr(t, s));
-
-}
diff --git a/sources/scala/xml/ProcInstr.scala b/sources/scala/xml/ProcInstr.scala
index 8b9669ab61..7a5ce461d6 100644
--- a/sources/scala/xml/ProcInstr.scala
+++ b/sources/scala/xml/ProcInstr.scala
@@ -18,6 +18,11 @@ package scala.xml;
case class ProcInstr(target:String, text:String) extends SpecialNode {
+ if( !Parsing.isName( target ) )
+ throw new IllegalArgumentException(target+" must be an XML Name");
+ else if( text.indexOf("?>" ) != -1 )
+ throw new IllegalArgumentException(text+" may not contain \"?>\"");
+
final override def typeTag$:Int = -2;
val z:Seq[Char] = target; z match {
@@ -25,14 +30,11 @@ case class ProcInstr(target:String, text:String) extends SpecialNode {
throw new IllegalArgumentException(target+" is reserved");
case _ =>
}
- if( !Parsing.isName( target ) )
- throw new IllegalArgumentException(target+" must be an XML Name");
- else if( text.indexOf("?>" ) != -1 )
- throw new IllegalArgumentException(text+" may not contain \"?>\"");
- final override def equals(x:Any) = x match {
- case x @ ProcInstr( t2, s2 ) => target.equals( t2 ) && text.equals( s2 );
- case _ => false;
+ /** structural equality */
+ override def equals(x: Any): Boolean = x match {
+ case ProcInstr(x,y) => x.equals(target) && y.equals(text);
+ case _ => false
}
/** the constant "#PI" */
@@ -41,15 +43,18 @@ case class ProcInstr(target:String, text:String) extends SpecialNode {
/** hashcode for this PI */
override def hashCode() = target.hashCode() * 7 + text.hashCode();
- /** returns &quot;&lt;?&quot;+target+(&quot; &quot;+text)?+&quot;?&gt;&quot; */
- final override def toString() = {
- val sb = new StringBuffer("<?");
- sb.append(target);
+ /** appends &quot;&lt;?&quot; target (&quot; &quot;+text)?+&quot;?&gt;&quot;
+ * to this stringbuffer.
+ */
+ def toString(sb: StringBuffer) = {
+ sb
+ .append("<?")
+ .append(target);
if( text.length() > 0 ) {
- sb.append(' ');
- sb.append(text);
+ sb
+ .append(' ')
+ .append(text);
};
sb.append("?>");
- sb.toString()
}
}
diff --git a/sources/scala/xml/SpecialNode.scala b/sources/scala/xml/SpecialNode.scala
index 9752400fd5..1162287e2f 100644
--- a/sources/scala/xml/SpecialNode.scala
+++ b/sources/scala/xml/SpecialNode.scala
@@ -14,13 +14,18 @@ package scala.xml;
**/
abstract class SpecialNode extends Node {
- /** always Node.EmptyNamespace */
- //final def namespace = Node.EmptyNamespace;
-
/** always empty */
- //final def attributes = Node.NoAttributes;
+ final override def attributes = Null;
+
+ /** always Node.EmptyNamespace */
+ final override def namespace = null;
/** always empty */
final def child = Nil;
+ final override def toString(): String =
+ toString(new StringBuffer()).toString();
+
+ def toString(sb:StringBuffer): StringBuffer ;
+
}
diff --git a/sources/scala/xml/Text.scala b/sources/scala/xml/Text.scala
index 95fec1104f..b784ae5b58 100644
--- a/sources/scala/xml/Text.scala
+++ b/sources/scala/xml/Text.scala
@@ -9,23 +9,20 @@
package scala.xml;
-import scala.collection.immutable ;
/** an XML node for text (PCDATA). Used in both non-bound and bound XML
* representations
* @author Burak Emir
* @param text the text contained in this node, may not be null.
-**/
-
-
+ */
case class Text[+A]( data: A ) extends SpecialNode {
- /** @deprecated
- */
- def text = toString();
-
if(null == data)
throw new java.lang.NullPointerException("tried to construct Text with null");
+ /** @deprecated
+ */
+ def text = data.toString();
+
final override def typeTag$:Int = -1;
/** the constant "#PCDATA"
@@ -42,6 +39,7 @@ case class Text[+A]( data: A ) extends SpecialNode {
override def hashCode() = data.hashCode();
/** returns text, with some characters escaped according to XML spec */
- override def toString() = Utility.escape( data.toString() );
+ def toString(sb:StringBuffer) =
+ Utility.escape( data.toString(), sb );
}
diff --git a/sources/scala/xml/Utility.scala b/sources/scala/xml/Utility.scala
index 3dc9ee7b01..08ce7febce 100644
--- a/sources/scala/xml/Utility.scala
+++ b/sources/scala/xml/Utility.scala
@@ -9,10 +9,8 @@
package scala.xml;
-import java.lang.StringBuffer; /* Java dependency! */
+import java.lang.StringBuffer;
import scala.collection.mutable;
-import scala.collection.immutable;
-import scala.collection.Map;
/**
* Utility functions for processing instances of bound and not bound XML
@@ -23,8 +21,12 @@ object Utility {
def view(s: String): Text[String] = Text(s);
/* escapes the characters &lt; &gt; &amp; and &quot; from string */
- def escape(text: String) = {
- val s = new StringBuffer();
+ final def escape(text: String): String =
+ escape(text, new StringBuffer()).toString();
+
+
+ /* appends escaped string to s */
+ final def escape(text: String, s: StringBuffer): StringBuffer = {
for (val c <- Iterator.fromString(text)) c match {
case '<' => s.append("&lt;");
case '>' => s.append("&gt;");
@@ -32,55 +34,37 @@ object Utility {
case '"' => s.append("&quot;");
case _ => s.append(c);
}
- s.toString()
+ s
}
/**
- * Returns a set of all namespaces appearing in a node and all its
- * descendants, including the empty namespaces
+ * Returns a set of all namespaces used in a sequence of nodes
+ * and all their descendants, including the empty namespaces.
*
- * @param node
- def collectNamespaces(node: Node): mutable.Set[String] = {
- collectNamespaces(node, new mutable.HashSet[String]());
- }
+ * @param nodes
*/
- /**
- * Returns a set of all namespaces appearing in a sequence of nodes
- * and all their descendants, including the empty namespaces
- *
- * @param nodes
def collectNamespaces(nodes: Seq[Node]): mutable.Set[String] = {
var m = new mutable.HashSet[String]();
- for (val n <- nodes)
- collectNamespaces(n, m);
+ val it = nodes.elements;
+ while (it.hasNext)
+ collectNamespaces(it.next, m);
m
}
- private def collectNamespaces(node: Node, set: mutable.Set[String]): mutable.Set[String] = {
- def collect( n:Node ):Unit = {
- if( n.typeTag$ >= 0 ) {
- set += n.namespace;
- for (val a <- n.attributes)
- a.match {
- case _:PrefixedAttribute =>
- set += a.getNamespace(n)
- case _ =>
- }
- for (val i <- n.child)
- collect(i);
- }
+ /** adds all namespaces in node to set */
+ def collectNamespaces(n: Node, set: mutable.Set[String]): Unit = {
+ if( n.typeTag$ >= 0 ) {
+ set += n.namespace;
+ for (val a <- n.attributes) a.match {
+ case _:PrefixedAttribute =>
+ set += a.getNamespace(n)
+ case _ =>
+ }
+ for (val i <- n.child)
+ collectNamespaces(i, set);
}
- collect(node);
- set
}
- */
-
- /**
- * A prefix mapping that maps the empty namespace to the empty prefix
- */
- val noPrefixes: Map[String,String] =
- immutable.ListMap.Empty[String,String].update("","");
/** string representation of an XML node, with comments stripped the comments
* @see "toXML(Node, Boolean)"
@@ -103,37 +87,26 @@ object Utility {
}
- /** serializes a tree to the given stringbuffer
- * with the given namespace prefix mapping.
- * elements and attributes that have namespaces not in pmap are <strong>ignored</strong>
+ /** appends a tree to the given stringbuffer within given namespace scope.
+ *
* @param n the node
* @param pscope the parent scope
* @param sb stringbuffer to append to
* @param stripComment if true, strip comments
*/
def toXML(x: Node, pscope: NamespaceBinding, sb: StringBuffer, stripComment: Boolean): Unit = {
- //Console.println("inside toXML, x.label = "+x.label);
- //Console.println("inside toXML, x.scope = "+x.scope);
- //Console.println("inside toXML, pscope = "+pscope);
x match {
- case Text(t) =>
- sb.append(escape(t.toString()));
-
- case Comment(text) =>
- if (!stripComment) {
- sb.append("<!--");
- sb.append(text);
- sb.append("-->");
- }
+ case c: Comment if !stripComment =>
+ c.toString(sb)
- case _ if x.typeTag$ < 0 =>
- sb.append( x.toString() );
+ case x: SpecialNode =>
+ x.toString(sb)
- case _ => {
+ case _ =>
// print tag with namespace declarations
sb.append('<');
- x.nameToString(sb); //appendPrefixedName( x.prefix, x.label, pmap, sb );
+ x.nameToString(sb);
if (x.attributes != null) {
x.attributes.toString(sb)
}
@@ -143,9 +116,9 @@ object Utility {
toXML(c, x.scope, sb, stripComment);
}
sb.append("</");
- x.nameToString(sb); //appendPrefixedName(x.prefix, x.label, pmap, sb);
+ x.nameToString(sb);
sb.append('>')
- }
+
}
}
diff --git a/sources/scala/xml/nobinding/NoBindingFactoryAdapter.scala b/sources/scala/xml/nobinding/NoBindingFactoryAdapter.scala
deleted file mode 100644
index 25563f8ecc..0000000000
--- a/sources/scala/xml/nobinding/NoBindingFactoryAdapter.scala
+++ /dev/null
@@ -1,61 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2004, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-** $Id$
-\* */
-package scala.xml.nobinding;
-
-import scala.collection.mutable;
-import org.xml.sax.InputSource;
-
-/** nobinding adaptor providing callbacks to parser to create elements.
-* implements hash-consing
-*/
-class NoBindingFactoryAdapter extends FactoryAdapter with NodeFactory[Elem] {
-
-
- // FactoryAdapter methods
-
- /** returns true. Every XML node may contain text that the application needs
- **/
- def nodeContainsText( label:java.lang.String ):boolean = true;
-
-
- // methods for NodeFactory[Elem]
- protected def create(pre: String, label: String, attrs: MetaData, scpe: NamespaceBinding, children:Seq[Node]): Elem = {
- Elem( pre, label, attrs, scpe, children:_* );
- }
-
- // methods for FactoryAdapter
-
- /** creates a node. never creates the same node twice, using hash-consing
- */
- def createNode(pre:String, label: String, attrs: MetaData, scpe: NamespaceBinding, children: List[Node] ): Elem = {
- //Console.println("NoBindingFactoryAdapter::createNode("+pre+","+label+","+attrs+","+scpe+","+children+")");
- Elem( pre, label, attrs, scpe, children:_* );
-
- //makeNode(pre, label, attrs, scope, children);
- }
-
- /** creates a text node
- */
- def createText( text:String ) =
- Text( text );
-
- /** loads an XML document, returning a Symbol node.
- */
- override def loadXML( source:InputSource ):Elem =
- super.loadXML( source ).asInstanceOf[ Elem ];
-
- def getDefaultNamespace(it:Iterator[Pair[String,String]]):String = {
- while( it.hasNext ) {
- val key = it.next;
- if( key._1 == "xmlns")
- return key._2
- }
- return "";
- }
- }
diff --git a/sources/scala/xml/nobinding/XML.scala b/sources/scala/xml/nobinding/XML.scala
deleted file mode 100644
index d762ccea39..0000000000
--- a/sources/scala/xml/nobinding/XML.scala
+++ /dev/null
@@ -1,76 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2004, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-** $Id$
-\* */
-package scala.xml.nobinding ;
-
-import org.xml.sax.InputSource;
-import scala.collection.Map ;
-import scala.collection.mutable.HashMap ;
-
-// import scala.xml.Utility ;
-
-/** functions to load and save XML elements. use this when data binding is not
-** desired, i.e. when XML is handled using Symbol nodes
-**/
-object XML {
-
- import java.io._ ;
-
- // functions for generic xml loading, saving
-
- /** loads XML from given file */
- def loadFile( file:File ):scala.xml.Elem =
- new NoBindingFactoryAdapter().loadXML( new InputSource(
- new FileInputStream( file )
- ));
-
- /** loads XML from given file descriptor */
- def loadFile( fileDesc:FileDescriptor ):scala.xml.Elem =
- new NoBindingFactoryAdapter().loadXML( new InputSource(
- new FileInputStream( fileDesc )
- ));
-
- /** loads XML from given file */
- def loadFile( fileName:String ):scala.xml.Elem =
- new NoBindingFactoryAdapter().loadXML( new InputSource(
- new FileInputStream( fileName )
- ));
-
- /** loads XML from given InputStream */
- def load( is:InputStream ):scala.xml.Elem =
- new NoBindingFactoryAdapter().loadXML( new InputSource( is ));
-
- /** loads XML from given Reader */
- def load( reader:Reader ):scala.xml.Elem =
- new NoBindingFactoryAdapter().loadXML( new InputSource( reader ));
-
- /** loads XML from given sysID */
- def load( sysID:String ):scala.xml.Elem =
- new NoBindingFactoryAdapter().loadXML( new InputSource( sysID ));
-
- /** loads XML from a given input source*/
- def load( source:InputSource ):scala.xml.Elem =
- new NoBindingFactoryAdapter().loadXML( source );
-
- /** saves XML to filename with encoding ISO-8859-1 */
- def save( filename:String, doc:Elem ):Unit = {
- /* using NIO classes of JDK 1.4 */
- import java.io.{FileOutputStream,Writer};
- import java.nio.channels.{Channels,FileChannel};
-
- val fos = new FileOutputStream( filename );
- val w:Writer = Channels.newWriter( fos.getChannel(), "ISO-8859-1" );
-
- /* 2do: optimize by giving writer parameter to toXML*/
- w.write( Utility.toXML( doc ));
-
- w.close();
- fos.close();
- }
-
-}
diff --git a/test/files/jvm/xml01.scala b/test/files/jvm/xml01.scala
index f97732a68e..3d2c7a2731 100644
--- a/test/files/jvm/xml01.scala
+++ b/test/files/jvm/xml01.scala
@@ -1,7 +1,6 @@
import java.io.StringReader;
import org.xml.sax.InputSource;
import scala.xml._;
-import scala.xml.nobinding._;
import scala.util.logging._;
import scala.testing.UnitTest._ ;
@@ -18,8 +17,9 @@ object Test with Application {
val c = new Node {
def label = "hello";
- //def namespace = "";
- def child = List(Elem("","world",e,sc));
+ override def hashCode() =
+ Utility.hashCode(prefix, label, attributes.hashCode(), scope.hashCode(), child);
+ def child = Elem(null, "world", e, sc);
//def attributes = e;
};
@@ -36,10 +36,10 @@ object Test with Application {
val i = new InputSource( new StringReader( x2 ));
val x2p = XML.load( i );
- assertEquals(x2p, Elem("","book",e,sc,
- Elem("","author",e,sc,Text("Peter Buneman")),
- Elem("","author",e,sc,Text("Dan Suciu")),
- Elem("","title",e,sc,Text("Data on ze web"))));
+ assertEquals(x2p, Elem(null,"book",e,sc,
+ Elem(null,"author",e,sc,Text("Peter Buneman")),
+ Elem(null,"author",e,sc,Text("Dan Suciu")),
+ Elem(null,"title",e,sc,Text("Data on ze web"))));
val xmlFile2 = "<bib><book><author>Peter Buneman</author><author>Dan Suciu</author><title>Data on ze web</title></book><book><author>John Mitchell</author><title>Foundations of Programming Languages</title></book></bib>";
val isrc2 = new InputSource( new StringReader( xmlFile2 ) );
@@ -49,9 +49,9 @@ object Test with Application {
Console.println("xpath \\");
- assertSameElements( parsedxml1 \ "_" , List( Elem("","world",e,sc) ) );
+ assertSameElements( parsedxml1 \ "_" , List( Elem(null,"world",e,sc) ) );
- assertSameElements( parsedxml1 \ "world", List( Elem("","world",e,sc) ) );
+ assertSameElements( parsedxml1 \ "world", List( Elem(null,"world",e,sc) ) );
/*
Console.println( parsedxml2 \ "_" );
@@ -65,13 +65,13 @@ object Test with Application {
parsedxml2 \ "_" ,
List(
- Elem("","book", e,sc,
- Elem("","author",e,sc,Text("Peter Buneman")),
- Elem("","author",e,sc,Text("Dan Suciu")),
- Elem("","title",e,sc,Text("Data on ze web"))),
- Elem("","book",e,sc,
- Elem("","author",e,sc,Text("John Mitchell")),
- Elem("","title",e,sc,Text("Foundations of Programming Languages"))))
+ Elem(null,"book", e,sc,
+ Elem(null,"author",e,sc,Text("Peter Buneman")),
+ Elem(null,"author",e,sc,Text("Dan Suciu")),
+ Elem(null,"title",e,sc,Text("Data on ze web"))),
+ Elem(null,"book",e,sc,
+ Elem(null,"author",e,sc,Text("John Mitchell")),
+ Elem(null,"title",e,sc,Text("Foundations of Programming Languages"))))
);
assertEquals( (parsedxml2 \ "author").length, 0 );
@@ -79,13 +79,13 @@ object Test with Application {
parsedxml2 \ "book",
List(
- Elem("","book",e,sc,
- Elem("","author",e,sc,Text("Peter Buneman")),
- Elem("","author",e,sc,Text("Dan Suciu")),
- Elem("","title",e,sc,Text("Data on ze web"))),
- Elem("","book",e,sc,
- Elem("","author",e,sc,Text("John Mitchell")),
- Elem("","title",e,sc,Text("Foundations of Programming Languages")))
+ Elem(null,"book",e,sc,
+ Elem(null,"author",e,sc,Text("Peter Buneman")),
+ Elem(null,"author",e,sc,Text("Dan Suciu")),
+ Elem(null,"title",e,sc,Text("Data on ze web"))),
+ Elem(null,"book",e,sc,
+ Elem(null,"author",e,sc,Text("John Mitchell")),
+ Elem(null,"title",e,sc,Text("Foundations of Programming Languages")))
)
);
@@ -94,11 +94,11 @@ object Test with Application {
parsedxml2 \ "_" \ "_",
List(
- Elem("","author",e,sc,Text("Peter Buneman")),
- Elem("","author",e,sc,Text("Dan Suciu")),
- Elem("","title",e,sc,Text("Data on ze web")),
- Elem("","author",e,sc,Text("John Mitchell")),
- Elem("","title",e,sc,Text("Foundations of Programming Languages"))
+ Elem(null,"author",e,sc,Text("Peter Buneman")),
+ Elem(null,"author",e,sc,Text("Dan Suciu")),
+ Elem(null,"title",e,sc,Text("Data on ze web")),
+ Elem(null,"author",e,sc,Text("John Mitchell")),
+ Elem(null,"title",e,sc,Text("Foundations of Programming Languages"))
)
);
@@ -107,9 +107,9 @@ object Test with Application {
parsedxml2 \ "_" \ "author",
List(
- Elem("","author",e,sc,Text("Peter Buneman")),
- Elem("","author",e,sc,Text("Dan Suciu")),
- Elem("","author",e,sc,Text("John Mitchell"))
+ Elem(null,"author",e,sc,Text("Peter Buneman")),
+ Elem(null,"author",e,sc,Text("Dan Suciu")),
+ Elem(null,"author",e,sc,Text("John Mitchell"))
)
);
@@ -123,9 +123,9 @@ object Test with Application {
parsedxml2 \\ "author",
List(
- Elem("","author",e,sc,Text("Peter Buneman")),
- Elem("","author",e,sc,Text("Dan Suciu")),
- Elem("","author",e,sc,Text("John Mitchell"))
+ Elem(null,"author",e,sc,Text("Peter Buneman")),
+ Elem(null,"author",e,sc,Text("Dan Suciu")),
+ Elem(null,"author",e,sc,Text("John Mitchell"))
)
);
@@ -134,30 +134,30 @@ object Test with Application {
(new NodeSeq { val theSeq = List( parsedxml2 ) }) \\ "_",
List(
- Elem("","bib",e,sc,
- Elem("","book",e,sc,
- Elem("","author",e,sc,Text("Peter Buneman")),
- Elem("","author",e,sc,Text("Dan Suciu")),
- Elem("","title",e,sc,Text("Data on ze web"))),
- Elem("","book",e,sc,
- Elem("","author",e,sc,Text("John Mitchell")),
- Elem("","title",e,sc,Text("Foundations of Programming Languages")))),
- Elem("","book",e,sc,
- Elem("","author",e,sc,Text("Peter Buneman")),
- Elem("","author",e,sc,Text("Dan Suciu")),
- Elem("","title",e,sc,Text("Data on ze web"))),
- Elem("","author",e,sc,Text("Peter Buneman")),
+ Elem(null,"bib",e,sc,
+ Elem(null,"book",e,sc,
+ Elem(null,"author",e,sc,Text("Peter Buneman")),
+ Elem(null,"author",e,sc,Text("Dan Suciu")),
+ Elem(null,"title",e,sc,Text("Data on ze web"))),
+ Elem(null,"book",e,sc,
+ Elem(null,"author",e,sc,Text("John Mitchell")),
+ Elem(null,"title",e,sc,Text("Foundations of Programming Languages")))),
+ Elem(null,"book",e,sc,
+ Elem(null,"author",e,sc,Text("Peter Buneman")),
+ Elem(null,"author",e,sc,Text("Dan Suciu")),
+ Elem(null,"title",e,sc,Text("Data on ze web"))),
+ Elem(null,"author",e,sc,Text("Peter Buneman")),
Text("Peter Buneman"),
- Elem("","author",e,sc,Text("Dan Suciu")),
+ Elem(null,"author",e,sc,Text("Dan Suciu")),
Text("Dan Suciu"),
- Elem("","title",e,sc,Text("Data on ze web")),
+ Elem(null,"title",e,sc,Text("Data on ze web")),
Text("Data on ze web"),
- Elem("","book",e,sc,
- Elem("","author",e,sc,Text("John Mitchell")),
- Elem("","title",e,sc,Text("Foundations of Programming Languages"))),
- Elem("","author",e,sc,Text("John Mitchell")),
+ Elem(null,"book",e,sc,
+ Elem(null,"author",e,sc,Text("John Mitchell")),
+ Elem(null,"title",e,sc,Text("Foundations of Programming Languages"))),
+ Elem(null,"author",e,sc,Text("John Mitchell")),
Text("John Mitchell"),
- Elem("","title",e,sc,Text("Foundations of Programming Languages")),
+ Elem(null,"title",e,sc,Text("Foundations of Programming Languages")),
Text("Foundations of Programming Languages")
)
);
@@ -168,7 +168,7 @@ object Test with Application {
parsedxml2 \\ "title",
List(
- Elem("","title",e,sc,Text("Data on ze web")),
- Elem("","title",e,sc,Text("Foundations of Programming Languages")))
+ Elem(null,"title",e,sc,Text("Data on ze web")),
+ Elem(null,"title",e,sc,Text("Foundations of Programming Languages")))
);
}
diff --git a/test/files/jvm/xmlstuff.scala b/test/files/jvm/xmlstuff.scala
index 1418707f95..90ae82e18a 100644
--- a/test/files/jvm/xmlstuff.scala
+++ b/test/files/jvm/xmlstuff.scala
@@ -1,8 +1,7 @@
import java.io.StringReader;
import org.xml.sax.InputSource;
-import scala.xml.nobinding.XML;
import scala.testing.UnitTest._ ;
-import scala.xml.{Node,NodeSeq,Elem,Text};
+import scala.xml.{Node, NodeSeq, Elem, Text, XML};
object Test with Application {