diff options
author | buraq <buraq@epfl.ch> | 2004-06-03 07:57:25 +0000 |
---|---|---|
committer | buraq <buraq@epfl.ch> | 2004-06-03 07:57:25 +0000 |
commit | 446d90a2b078389c1545617dbf93a18f8b68077a (patch) | |
tree | dc60a71b15bc037f3fccfdb692089957e4c36e32 /sources | |
parent | e3deada17d62560024239252d4ed24fbbdda58bb (diff) | |
download | scala-446d90a2b078389c1545617dbf93a18f8b68077a.tar.gz scala-446d90a2b078389c1545617dbf93a18f8b68077a.tar.bz2 scala-446d90a2b078389c1545617dbf93a18f8b68077a.zip |
attribute valid
Diffstat (limited to 'sources')
-rw-r--r-- | sources/scala/tools/dtd2scala/DeclToScala.scala | 76 | ||||
-rw-r--r-- | sources/scala/tools/dtd2scala/template/ObjectTemplate.scala.xml | 54 | ||||
-rw-r--r-- | sources/scala/xml/BindingFactoryAdapter.scala | 6 | ||||
-rw-r--r-- | sources/scala/xml/Utility.scala | 1 | ||||
-rw-r--r-- | sources/scala/xml/dtd/Decl.scala | 7 |
5 files changed, 120 insertions, 24 deletions
diff --git a/sources/scala/tools/dtd2scala/DeclToScala.scala b/sources/scala/tools/dtd2scala/DeclToScala.scala index 88f0f7ae4e..074879b1ba 100644 --- a/sources/scala/tools/dtd2scala/DeclToScala.scala +++ b/sources/scala/tools/dtd2scala/DeclToScala.scala @@ -10,7 +10,8 @@ import scala.collection.Map ; import scala.collection.mutable.HashMap ; import scala.xml._ ; -import scala.xml.dtd.{AttrDecl,RegExp,ANY_,PCDATA_,Eps,Star,RNode,Sequ,Alt}; +import scala.xml.dtd.{AttrDecl,RegExp,ANY_,PCDATA_,Eps,Star,RNode,Sequ,Alt} +import scala.xml.dtd.{REQUIRED,IMPLIED,DEFAULT}; import scala.xml.nobinding.XML ; /** transforms a set of DTD declaraion to a scala source file. @@ -31,6 +32,71 @@ class DeclToScala(fOut:PrintWriter, var curAttribs: Map[String,AttrDecl] = null ; /* of current elem */ var curModel : RegExp = null; + /** 1.populate with special "<R" and default + **/ + def initAttributes( curAttribs:Map[String,AttrDecl] ):String = { + val sb = new StringBuffer(); + for( val key <- curAttribs.keys ) { + curAttribs( key ).default match { + case REQUIRED => + sb.append("map = map.update(\""); + sb.append( key ); + sb.append("\", "); + sb.append("\"<R\"); req=req+1; // REQUIRED"); + case IMPLIED => + /* no default value */ + case DEFAULT( _, attValue ) => + sb.append("map = map.update(\""); + sb.append( key ); + sb.append("\", \""); + sb.append(attValue); /* quotes??? */ + sb.append("\")"); + } + sb.append('\n'); + } + sb.toString(); + } + /** 1.populate with actual values: throw error if FIXED is wrong + ** 2.throw error if a REQUIRED one is missing*/ + def validateAttributes( curAttribs:Map[String,AttrDecl] ):String = { + def appendKey( key:String, sb:StringBuffer ) = { + val it = Iterator.fromString( key ); + sb.append('\''); + sb.append( it.next ); + sb.append('\''); + it.foreach { + c => + sb.append(','); + sb.append('\''); + sb.append( c ); + sb.append('\'') + } + } + val sb = new StringBuffer(); + for( val key <- curAttribs.keys ) { + sb.append(" case Seq("); + curAttribs( key ) match { + case AttrDecl( key, tpe, df ) => + appendKey( key, sb ); + sb.append(") =>"); + df match { + case DEFAULT( true, attValue ) => + sb.append("if( b._2 != \"+"); + sb.append( attValue ); + sb.append("+\" ) error_FixedAttribute(b._1,"); + sb.append( attValue ); + sb.append(")"); + case REQUIRED => + sb.append(" req = req - 1; map = map.update( b._1, b._2 )"); + case _ => + sb.append(" map = map.update( b._1, b._2 )"); + } + } + sb.append('\n'); + } + sb.toString(); + } + def shallowValidate( r:RegExp ):String = { def shallowContentModel1(rs:List[RegExp],sep:Char):String = { @@ -47,7 +113,7 @@ class DeclToScala(fOut:PrintWriter, } def shallowContentModel(r:RegExp):String = { - //Console.println("sCM:"+ r.getClass() + " r:"+r ); + /*Console.println("sCM:"+ r.getClass() + " r:"+r );*/ r match { case Eps => "" case RNode(name) => "$TagOf" + cookedCap( name ); @@ -58,7 +124,7 @@ class DeclToScala(fOut:PrintWriter, } } - //Console.println("shallowValid:"+ r.getClass() + " r:"+r ); + /*Console.println("shallowValid:"+ r.getClass() + " r:"+r );*/ r match { case ANY_ => "true"; case Eps => "ch.length == 0" @@ -124,6 +190,10 @@ class DeclToScala(fOut:PrintWriter, lookup.update("compressDefault", compress.toString()); n.child.elements.foreach { n => writeNode(n) } } + case "initAttributes" => + fOut.print( initAttributes( curAttribs ) ); + case "validateAttributes" => + fOut.print( validateAttributes( curAttribs ) ); case "shallowContentRegExp" => fOut.print( shallowValidate( curModel ) ); case "elementTag" => diff --git a/sources/scala/tools/dtd2scala/template/ObjectTemplate.scala.xml b/sources/scala/tools/dtd2scala/template/ObjectTemplate.scala.xml index 97891442cf..a8a948460f 100644 --- a/sources/scala/tools/dtd2scala/template/ObjectTemplate.scala.xml +++ b/sources/scala/tools/dtd2scala/template/ObjectTemplate.scala.xml @@ -27,34 +27,58 @@ import scala.collection.immutable; import scala.collection.mutable; - type cT = scala.Seq[scala.xml.Node]; type aT = Map[String,String]; + def error_FixedAttribute( k:String, value:String ) = + error("value of attribute " + k + " FIXED to \""+value+"\""); + + def error_UndefinedAttribute( b:String ) = + error("undefined attribute " + b ); + + def error_MissingAttribute( map:aT ) = + error("missing value for REQUIRED attribute " + +(map.keys.filter { x => map(x) == "<R" }) + .toList.mkString("",",","")); + abstract class <string ref="objectName"/>Node$ extends scala.xml.Node; <elementBinding> - val $TagOf&ccElementName;:int = <elementTag/>; - def constr_&ccElementName;( ch:cT, attrs:aT ) = new &ccElementName;(ch:_*) { - override var hmap = attrs; - override val attribHashCode = attrs.toList.hashCode() ; - }; + val $TagOf&ccElementName;:int = <elementTag/>; + + def constr_&ccElementName;( attrs:aT, ch:cT ) = &ccElementName;(attrs,ch:_*); + + case class &ccElementName;( attrs:Map[String,String], ch:scala.xml.Node* ) extends <string ref="objectName"/>Node$ { + + + final override def typeTag$ = $TagOf&ccElementName;; def shallowValidate&ccElementName;Children( ch:Seq[scala.xml.Node] ) = <shallowContentRegExp/>; + def validateAttributes( attrs:Map[String,String] ):aT = { + var req = 0; + var map = scala.xml.Node.NoAttributes; + <initAttributes/> - case class &ccElementName;( ch:scala.xml.Node* ) extends <string ref="objectName"/>Node$ { - - final override def typeTag$ = $TagOf&ccElementName;; + for( val b <- attrs.elements ) { + val a:Seq[Char] = b._1; + a match { + <validateAttributes/> + case _ => error_UndefinedAttribute( b._1 ) + } + } + if( req > 0 ) error_MissingAttribute( map ); + map + } - if( !shallowValidate&ccElementName;Children( ch ) ) + if( !shallowValidate&ccElementName;Children( ch ) ) error("trying to construct invalid &elementName;"); def label = &qElementName;; def child = ch; - protected var hmap:aT = scala.xml.Node.NoAttributes; + protected var hmap:aT = validateAttributes( attrs ); final def attribute:aT = hmap; <attributeBinding> @@ -71,7 +95,7 @@ for( val p <- attrs ) { newmap = newmap.update( p._1, p._2 ) } - constr_&ccElementName;( child, newmap ) ; + &ccElementName;( newmap, child:_* ) ; } /** returns a new &ccElementName; with updated attribute */ @@ -81,7 +105,7 @@ newmap = newmap.update( p._1, p._2 ); }; newmap = newmap.update( attr._1, attr._2 ); - constr_&ccElementName;( child, newmap ) ; + &ccElementName;( newmap, child:_* ) ; } } </elementBinding> @@ -92,9 +116,9 @@ def load( filename:String, _compress:boolean ):scala.xml.Node = { val fAdapter = new scala.xml.BindingFactoryAdapter { val f = { - val res = new mutable.HashMap[String, (cT,aT) => scala.xml.Node]() ; + val res = new mutable.HashMap[String, (aT,cT) => scala.xml.Node]() ; <elementBinding> - res.update( &qElementName;, (x:cT,aMap:aT) => constr_&ccElementName;(x,aMap));</elementBinding> + res.update( &qElementName;, constr_&ccElementName;);</elementBinding> res; } diff --git a/sources/scala/xml/BindingFactoryAdapter.scala b/sources/scala/xml/BindingFactoryAdapter.scala index 3311b01887..d007427ac5 100644 --- a/sources/scala/xml/BindingFactoryAdapter.scala +++ b/sources/scala/xml/BindingFactoryAdapter.scala @@ -21,7 +21,7 @@ abstract class BindingFactoryAdapter extends FactoryAdapter() { /** mapping from element names to an element constructor * (constr:Seq[Node],HashMap[String,String] => Node) */ - val f: Map[ String, (Seq[Node],HashMap[String,String]) => Node ]; + val f: Map[ String, (HashMap[String,String],Seq[Node]) => Node ]; /** mapping from element names to a truth value indicating * whether the corresponding element may have text children @@ -46,7 +46,7 @@ abstract class BindingFactoryAdapter extends FactoryAdapter() { if( !compress ) { // get constructor val c = f( elemName ); - c( children, attribs ); + c( attribs, children ); } else { // do hash-consing val ahc = attribs.toList.hashCode(); @@ -61,7 +61,7 @@ abstract class BindingFactoryAdapter extends FactoryAdapter() { case None => // get constructor val c = f( elemName ); - val el = c( children, attribs ); + val el = c( attribs, children ); cache.update( h, el ); el } diff --git a/sources/scala/xml/Utility.scala b/sources/scala/xml/Utility.scala index df95177ed3..685c40c334 100644 --- a/sources/scala/xml/Utility.scala +++ b/sources/scala/xml/Utility.scala @@ -91,6 +91,7 @@ object Utility { } } + /** for a Node n, returns string representation of n.attributes **/ def attr2xml( attrib:Iterator[Pair[String, String]] ):String = { val t = new StringBuffer(); diff --git a/sources/scala/xml/dtd/Decl.scala b/sources/scala/xml/dtd/Decl.scala index a409c8805c..2294641a34 100644 --- a/sources/scala/xml/dtd/Decl.scala +++ b/sources/scala/xml/dtd/Decl.scala @@ -25,15 +25,16 @@ case class ElemDecl( name:String , def containsText = contentModel.indexOf("#PCDATA") != -1 ; }; -/* ignore default values 4 now */ +/** an attribute declaration */ case class AttrDecl( name:String, tpe:String, default:DefaultDecl ) extends MarkupDecl; -/* ignore default values 4 now */ +/** an entity declaration */ case class EntityDecl( name:String, tpe:String ) extends MarkupDecl; -/* ignore default values 4 now */ +/** a notation declaration */ case class NotationDecl( name:String, tpe:String ) extends MarkupDecl; +/** a parsed entity reference */ case class PEReference(ent:String) extends Decl { if( !Utility.isName( ent )) throw new IllegalArgumentException("ent must be an XML Name"); |