All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.com.fleeksoft.ksoup.select.CombiningEvaluator.kt Maven / Gradle / Ivy

Go to download

Ksoup is a Kotlin Multiplatform library for working with HTML and XML, and offers an easy-to-use API for URL fetching, data parsing, extraction, and manipulation using DOM and CSS selectors.

The newest version!
package com.fleeksoft.ksoup.select

import com.fleeksoft.ksoup.internal.StringUtil
import com.fleeksoft.ksoup.nodes.Element

/**
 * Base combining (and, or) evaluator.
 */
internal abstract class CombiningEvaluator internal constructor() : Evaluator() {
    // maintain original order so that #toString() is sensible
    val evaluators: ArrayList = ArrayList()
    val sortedEvaluators: ArrayList = ArrayList()
    var num = 0
    private var _cost = 0

    internal constructor(evaluators: Collection) : this() {
        this.evaluators.addAll(evaluators)
        updateEvaluators()
    }

    override fun reset() {
        for (evaluator in evaluators) {
            evaluator.reset()
        }
        super.reset()
    }

    override fun cost(): Int {
        return _cost
    }

    fun rightMostEvaluator(): Evaluator? {
        return if (num > 0) evaluators[num - 1] else null
    }

    fun replaceRightMostEvaluator(replacement: Evaluator) {
        evaluators[num - 1] = replacement
        updateEvaluators()
    }

    fun updateEvaluators() {
        // used so we don't need to bash on size() for every match test
        num = evaluators.size

        // sort the evaluators by lowest cost first, to optimize the evaluation order
        _cost = 0
        for (evaluator in evaluators) {
            _cost += evaluator.cost()
        }
        sortedEvaluators.clear()
        sortedEvaluators.addAll(evaluators)
        sortedEvaluators.sortWith { a, b -> a.cost() - b.cost() }
    }

    // ^ comparingInt, sortedEvaluators.sort not available in targeted version
    class And internal constructor(evaluators: Collection) :
        CombiningEvaluator(evaluators) {
            internal constructor(vararg evaluators: Evaluator) : this(evaluators.toList())

            override fun matches(
                root: Element,
                element: Element,
            ): Boolean {
                for (i in 0 until num) {
                    val s: Evaluator = sortedEvaluators[i]
                    if (!s.matches(root, element)) return false
                }
                return true
            }

            override fun toString(): String {
                return StringUtil.join(evaluators, "")
            }
        }

    class Or : CombiningEvaluator {
        /**
         * Create a new Or evaluator. The initial evaluators are ANDed together and used as the first clause of the OR.
         * @param evaluators initial OR clause (these are wrapped into an AND evaluator).
         */
        internal constructor(evaluators: Collection) : super() {
            if (num > 1) {
                this.evaluators.add(And(evaluators))
            } else {
                // 0 or 1
                this.evaluators.addAll(evaluators)
            }
            updateEvaluators()
        }

        internal constructor(vararg evaluators: Evaluator) : this(evaluators.toList())
        internal constructor() : super()

        fun add(e: Evaluator) {
            evaluators.add(e)
            updateEvaluators()
        }

        override fun matches(
            root: Element,
            element: Element,
        ): Boolean {
            for (i in 0 until num) {
                val s: Evaluator = sortedEvaluators[i]
                if (s.matches(root, element)) return true
            }
            return false
        }

        override fun toString(): String {
            return StringUtil.join(evaluators, ", ")
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy