package scales.xml.parser.strategies
import scales.xml._
import scales.utils.collection.{Tree, ImmutableArrayProxy}
import scales.xml.impl.{NotFromParser, IsFromParser, FromParser}
import ImmutableArrayProxy.one
import impl.TreeProxies
trait TreeOptimisation[TOKEN <: OptimisationToken] extends PathOptimisationStrategy[TOKEN] {
def newTree( elem : Elem, children : XmlChildren, token : TOKEN ) : XmlTree
final override def elementEnd( xml : TreeProxies, token : TOKEN ) {
import ScalesXml.xmlCBF
val l = xml.current
val nt = newTree(l.elem, l.builder.result, token)
val d = xml.depth
val nd = d - 1
if (d > 0) {
xml.depth = nd
val c = xml.proxy( nd )
xml.current = c
c.builder.+=(nt)
} else {
xml.rootTree = nt
xml.depth = nd
}
}
}
abstract class NameValue(val name : QName, val text : String) extends Tree[XmlItem, Elem, XCC] {
def section : Elem
def children : XmlChildren = one(Text(text))
def copy( section : Elem = section, children : XmlChildren = children) : Tree[XmlItem, Elem, XCC] = {
import ScalesXml.fromParserDefault
LazyOptimisedTree(section, children)
}
}
class ElemValue(val section : Elem, val text : String) extends Tree[XmlItem, Elem, XCC] {
def children : XmlChildren = one(Text(text))
def copy( section : Elem = section, children : XmlChildren = children) : Tree[XmlItem, Elem, XCC] = {
import ScalesXml.fromParserDefault
LazyOptimisedTree(section, children)
}
}
object LazyOptimisedTree {
def apply( section : Elem, children : XmlChildren ) ( implicit fromParser : FromParser ) : XmlTree =
if (children.isEmpty)
Tree(section, children)
else {
val head = children.head
if (head.isLeft) {
val left = head.getLeft
if (left.isInstanceOf[Text] && children.size == 1) {
if (section.attributes.isEmpty && section.namespaces.isEmpty)
newNameValue(section.name, left.value)
else
new ElemValue(section, left.value)
} else Tree(section, children)
} else Tree(section, children)
}
def newNameValue( iname : QName, itext : String ) ( implicit fromParser : FromParser ) : NameValue =
if (fromParser eq NotFromParser)
new NameValue(iname, itext) {
def section : Elem = Elem(name)(NotFromParser)
}
else
new NameValue(iname, itext) {
def section : Elem = Elem(name)(IsFromParser)
}
}
object QNameTreeOptimisation extends TreeOptimisation[QNameToken] with QNameOptimisationT[QNameToken] with QNameTokenF {
def newTree( elem : Elem, children : XmlChildren, token : QNameToken ) : XmlTree =
LazyOptimisedTree( elem, children )(IsFromParser)
}
object QNameElemTreeOptimisation extends PathOptimisationStrategy[ElemToken] with ElemQNameOptimisationT[ElemToken] with TreeOptimisation[ElemToken] with ElemTokenF {
def newTree( elem : Elem, children : XmlChildren, token : ElemToken ) : XmlTree =
LazyOptimisedTree( elem, children )(IsFromParser)
}