124 lines
3.4 KiB
Swift
124 lines
3.4 KiB
Swift
//
|
|
// CombiningEvaluator.swift
|
|
// SwiftSoup
|
|
//
|
|
// Created by Nabil Chatbi on 23/10/16.
|
|
// Copyright © 2016 Nabil Chatbi.. All rights reserved.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
/**
|
|
* Base combining (and, or) evaluator.
|
|
*/
|
|
public class CombiningEvaluator : Evaluator {
|
|
|
|
public private(set) var evaluators: Array<Evaluator>;
|
|
var num : Int = 0;
|
|
|
|
public override init() {
|
|
evaluators = Array<Evaluator>();
|
|
super.init()
|
|
}
|
|
|
|
public init(_ evaluators: Array<Evaluator>) {
|
|
self.evaluators = evaluators
|
|
super.init()
|
|
updateNumEvaluators()
|
|
}
|
|
|
|
func rightMostEvaluator()->Evaluator? {
|
|
return num > 0 && evaluators.count > 0 ? evaluators[num - 1] : nil
|
|
}
|
|
|
|
func replaceRightMostEvaluator(_ replacement: Evaluator) {
|
|
evaluators[num - 1] = replacement
|
|
}
|
|
|
|
func updateNumEvaluators() {
|
|
// used so we don't need to bash on size() for every match test
|
|
num = evaluators.count
|
|
}
|
|
|
|
public final class And : CombiningEvaluator {
|
|
public override init(_ evaluators: Array<Evaluator>) {
|
|
super.init(evaluators);
|
|
}
|
|
|
|
public override init(_ evaluators: Evaluator...) {
|
|
super.init(evaluators);
|
|
}
|
|
|
|
public override func matches(_ root: Element, _ node: Element)->Bool {
|
|
for i in 0..<num
|
|
{
|
|
let s = evaluators[i]
|
|
do{
|
|
if (try !s.matches(root, node)){
|
|
return false;
|
|
}
|
|
}catch{}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public override func toString()->String {
|
|
let ar : [String] = evaluators.map { String($0.toString()) }
|
|
return StringUtil.join(ar, sep: " ");
|
|
}
|
|
}
|
|
|
|
public final 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).
|
|
*/
|
|
public override init(_ evaluators: Array<Evaluator>) {
|
|
super.init();
|
|
if (num > 1){
|
|
self.evaluators.append(And(evaluators));
|
|
}else{ // 0 or 1
|
|
self.evaluators.append(contentsOf: evaluators);
|
|
}
|
|
updateNumEvaluators();
|
|
}
|
|
|
|
override init(_ evaluators: Evaluator...) {
|
|
super.init();
|
|
if (num > 1){
|
|
self.evaluators.append(And(evaluators));
|
|
}else{ // 0 or 1
|
|
self.evaluators.append(contentsOf: evaluators);
|
|
}
|
|
updateNumEvaluators();
|
|
}
|
|
|
|
override init() {
|
|
super.init();
|
|
}
|
|
|
|
public func add(_ e: Evaluator) {
|
|
evaluators.append(e);
|
|
updateNumEvaluators();
|
|
}
|
|
|
|
public override func matches(_ root: Element, _ node: Element)->Bool {
|
|
for i in 0..<num
|
|
{
|
|
let s : Evaluator = evaluators[i]
|
|
do{
|
|
if (try s.matches(root, node)){
|
|
return true;
|
|
}
|
|
}catch{}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public override func toString()->String {
|
|
return ":or\(evaluators.map{String($0.toString())})"
|
|
}
|
|
}
|
|
}
|