diff --git a/build.sbt b/build.sbt index 3cfafab72..555155c57 100644 --- a/build.sbt +++ b/build.sbt @@ -92,6 +92,8 @@ lazy val xml = crossProject(JSPlatform, JVMPlatform) exclude[MissingClassProblem]("scala.xml.dtd.Scanner"), exclude[MissingClassProblem]("scala.xml.dtd.ContentModelParser$"), exclude[MissingClassProblem]("scala.xml.dtd.ContentModelParser"), + exclude[MissingClassProblem]("scala.xml.dtd.ElementValidator"), + exclude[MissingClassProblem]("scala.xml.dtd.ElementValidator"), exclude[MissingClassProblem]("scala.xml.factory.Binder"), exclude[MissingClassProblem]("scala.xml.parsing.ValidatingMarkupHandler"), exclude[MissingClassProblem]("scala.xml.persistent.CachedFileStorage"), diff --git a/shared/src/main/scala/scala/xml/dtd/ElementValidator.scala b/shared/src/main/scala/scala/xml/dtd/ElementValidator.scala deleted file mode 100644 index 31035989d..000000000 --- a/shared/src/main/scala/scala/xml/dtd/ElementValidator.scala +++ /dev/null @@ -1,135 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2002-2019, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala -package xml -package dtd - -import PartialFunction._ -import scala.collection.mutable -import scala.collection.Seq - -import ContentModel.ElemName -import MakeValidationException._ // @todo other exceptions - -import impl._ - -/** - * validate children and/or attributes of an element - * exceptions are created but not thrown. - */ -class ElementValidator() extends Function1[Node, Boolean] { - - private var exc: List[ValidationException] = Nil - - protected var contentModel: ContentModel = _ - protected var dfa: DetWordAutom[ElemName] = _ - protected var adecls: List[AttrDecl] = _ - - /** set content model, enabling element validation */ - def setContentModel(cm: ContentModel) = { - contentModel = cm - cm match { - case ELEMENTS(r) => - val nfa = ContentModel.Translator.automatonFrom(r, 1) - dfa = new SubsetConstruction(nfa).determinize - case _ => - dfa = null - } - } - - def getContentModel = contentModel - - /** set meta data, enabling attribute validation */ - def setMetaData(adecls: List[AttrDecl]): Unit = { this.adecls = adecls } - - def getIterable(nodes: Seq[Node], skipPCDATA: Boolean): Iterable[ElemName] = { - def isAllWhitespace(a: Atom[_]) = cond(a.data) { case s: String if s.trim == "" => true } - - nodes.filter { - case y: SpecialNode => y match { - case a: Atom[_] if isAllWhitespace(a) => false // always skip all-whitespace nodes - case _ => !skipPCDATA - } - case x => x.namespace eq null - }.map (x => ElemName(x.label)) - } - - /** - * check attributes, return true if md corresponds to attribute declarations in adecls. - */ - def check(md: MetaData): Boolean = { - val len: Int = exc.length - val ok = new mutable.BitSet(adecls.length) - - for (attr <- md) { - def attrStr = attr.value.toString - def find(Key: String): Option[AttrDecl] = { - adecls.zipWithIndex collectFirst { - case (a@AttrDecl(Key, _, _), j) => - ok += j - a - } - } - - find(attr.key) match { - case None => - exc ::= fromUndefinedAttribute(attr.key) - - case Some(AttrDecl(_, tpe, DEFAULT(true, fixedValue))) if attrStr != fixedValue => - exc ::= fromFixedAttribute(attr.key, fixedValue, attrStr) - - case _ => - } - } - - adecls.zipWithIndex foreach { - case (AttrDecl(key, tpe, REQUIRED), j) if !ok(j) => exc ::= fromMissingAttribute(key, tpe) - case _ => - } - - exc.length == len //- true if no new exception - } - - /** - * check children, return true if conform to content model - * @note contentModel != null - */ - def check(nodes: Seq[Node]): Boolean = contentModel match { - case ANY => true - case EMPTY => getIterable(nodes, skipPCDATA = false).isEmpty - case PCDATA => getIterable(nodes, skipPCDATA = true).isEmpty - case MIXED(ContentModel.Alt(branches@_*)) => // @todo - val j = exc.length - def find(Key: String): Boolean = - branches exists { case ContentModel.Letter(ElemName(Key)) => true; case _ => false } - - getIterable(nodes, skipPCDATA = true) map (_.name) filterNot find foreach { - exc ::= MakeValidationException fromUndefinedElement _ - } - (exc.length == j) // - true if no new exception - - case _: ELEMENTS => - dfa isFinal { - getIterable(nodes, skipPCDATA = false).foldLeft(0) { (q, e) => - (dfa delta q).getOrElse(e, throw ValidationException("element %s not allowed here" format e)) - } - } - case _ => false - } - - /** - * applies various validations - accumulates error messages in exc - * @todo fail on first error, ignore other errors (rearranging conditions) - */ - def apply(n: Node): Boolean = - //- ? check children - ((contentModel == null) || check(n.child)) && - //- ? check attributes - ((adecls == null) || check(n.attributes)) -} diff --git a/shared/src/test/scala/scala/xml/XMLTest.scala b/shared/src/test/scala/scala/xml/XMLTest.scala index d88b6c80e..7644ac645 100644 --- a/shared/src/test/scala/scala/xml/XMLTest.scala +++ b/shared/src/test/scala/scala/xml/XMLTest.scala @@ -176,57 +176,6 @@ class XMLTest { assertEquals(expected, actual) } - @UnitTest - def validationOfElements: Unit = { - val vtor = new scala.xml.dtd.ElementValidator(); - { - import scala.xml.dtd.ELEMENTS - import scala.xml.dtd.ContentModel._ - vtor.setContentModel( - ELEMENTS( - Sequ( - Letter(ElemName("bar")), - Star(Letter(ElemName("baz")))))); - } - assertTrue(vtor()) - - { - import scala.xml.dtd.MIXED - import scala.xml.dtd.ContentModel._ - - vtor.setContentModel( - MIXED( - Alt(Letter(ElemName("bar")), - Letter(ElemName("baz")), - Letter(ElemName("bal"))))); - } - - assertTrue(vtor()) - assertTrue(vtor(abcdedgh)) - assertFalse(vtor( )) - } - - def validationfOfAttributes: Unit = { - val vtor = new scala.xml.dtd.ElementValidator(); - vtor.setContentModel(null) - vtor.setMetaData(List()) - assertFalse(vtor()) - - { - import scala.xml.dtd._ - vtor setMetaData List(AttrDecl("bar", "CDATA", IMPLIED)) - } - assertFalse(vtor()) - assertTrue(vtor()) - - { - import scala.xml.dtd._ - vtor.setMetaData(List(AttrDecl("bar", "CDATA", REQUIRED))) - } - assertFalse(vtor()) - assertTrue(vtor()) - } - def Elem(prefix: String, label: String, attributes: MetaData, scope: NamespaceBinding, child: Node*): Elem = scala.xml.Elem.apply(prefix, label, attributes, scope, minimizeEmpty = true, child: _*)