eu.cdevreeze.xpathparser.queryapi.ElemLike.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of xpathparser_2.11 Show documentation
Show all versions of xpathparser_2.11 Show documentation
XPath parser and XPath AST API
/*
* Copyright 2011-2017 Chris de Vreeze
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.cdevreeze.xpathparser.queryapi
import scala.collection.immutable
import scala.reflect.ClassTag
/**
* Partial implementation of the ElemApi query API trait.
*
* @author Chris de Vreeze
*/
trait ElemLike[E <: ElemLike[E]] extends ElemApi[E] { self: E =>
import ElemApi.anyElem
def children: immutable.IndexedSeq[E]
// Finding topmost descendant elements (of a certain type, obeying some predicate)
final def findTopmostElems(p: E => Boolean): immutable.IndexedSeq[E] = {
children.flatMap(_.findTopmostElemsOrSelf(p))
}
final def findAllTopmostElemsOfType[A <: E](cls: ClassTag[A]): immutable.IndexedSeq[A] = {
findTopmostElemsOfType(cls)(anyElem)
}
final def findTopmostElemsOfType[A <: E](cls: ClassTag[A])(p: A => Boolean): immutable.IndexedSeq[A] = {
implicit val tag = cls
findTopmostElems {
case e: A if p(e) => true
case e => false
} collect {
case e: A => e
}
}
// Finding topmost descendant-or-self elements (of a certain type, obeying some predicate)
final def findTopmostElemsOrSelf(p: E => Boolean): immutable.IndexedSeq[E] = {
if (p(self)) {
immutable.IndexedSeq(self)
} else {
// Recursive calls
children.flatMap(_.findTopmostElemsOrSelf(p))
}
}
final def findAllTopmostElemsOrSelfOfType[A <: E](cls: ClassTag[A]): immutable.IndexedSeq[A] = {
findTopmostElemsOrSelfOfType(cls)(anyElem)
}
final def findTopmostElemsOrSelfOfType[A <: E](cls: ClassTag[A])(p: A => Boolean): immutable.IndexedSeq[A] = {
implicit val tag = cls
findTopmostElemsOrSelf {
case e: A if p(e) => true
case e => false
} collect {
case e: A => e
}
}
// Filtering descendant elements (of a certain type, obeying some predicate)
final def filterElems(p: E => Boolean): immutable.IndexedSeq[E] = {
children.flatMap(_.filterElemsOrSelf(p))
}
final def findAllElems: immutable.IndexedSeq[E] = {
filterElems(_ => true)
}
final def findAllElemsOfType[A <: E](cls: ClassTag[A]): immutable.IndexedSeq[A] = {
filterElemsOfType(cls)(anyElem)
}
final def filterElemsOfType[A <: E](cls: ClassTag[A])(p: A => Boolean): immutable.IndexedSeq[A] = {
implicit val tag = cls
filterElems {
case e: A if p(e) => true
case e => false
} collect {
case e: A => e
}
}
// Filtering descendant-or-self elements (of a certain type, obeying some predicate)
final def filterElemsOrSelf(p: E => Boolean): immutable.IndexedSeq[E] = {
// Recursive calls
immutable.IndexedSeq(self).filter(p) ++ children.flatMap(_.filterElemsOrSelf(p))
}
final def findAllElemsOrSelf: immutable.IndexedSeq[E] = {
filterElemsOrSelf(_ => true)
}
final def findAllElemsOrSelfOfType[A <: E](cls: ClassTag[A]): immutable.IndexedSeq[A] = {
filterElemsOrSelfOfType(cls)(anyElem)
}
final def filterElemsOrSelfOfType[A <: E](cls: ClassTag[A])(p: A => Boolean): immutable.IndexedSeq[A] = {
implicit val tag = cls
filterElemsOrSelf {
case e: A if p(e) => true
case e => false
} collect {
case e: A => e
}
}
// Finding an optional element (of a certain type, obeying some predicate)
final def findElem(p: E => Boolean): Option[E] = {
// Not very efficient
findTopmostElems(p).headOption
}
final def findFirstElemOfType[A <: E](cls: ClassTag[A]): Option[A] = {
findElemOfType(cls)(anyElem)
}
final def findElemOfType[A <: E](cls: ClassTag[A])(p: A => Boolean): Option[A] = {
implicit val tag = cls
findElem {
case e: A if p(e) => true
case e => false
} collectFirst {
case e: A => e
}
}
// Finding an optional element-or-self (of a certain type, obeying some predicate)
final def findElemOrSelf(p: E => Boolean): Option[E] = {
// Not very efficient
findTopmostElemsOrSelf(p).headOption
}
final def findFirstElemOrSelfOfType[A <: E](cls: ClassTag[A]): Option[A] = {
findElemOrSelfOfType(cls)(anyElem)
}
final def findElemOrSelfOfType[A <: E](cls: ClassTag[A])(p: A => Boolean): Option[A] = {
implicit val tag = cls
findElemOrSelf {
case e: A if p(e) => true
case e => false
} collectFirst {
case e: A => e
}
}
}