Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit f2c86aa1 authored by Wolf-Martell Montwé's avatar Wolf-Martell Montwé
Browse files

refactor(search): change SearchConditionTreeNode to Kotlin

parent 233484ca
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -170,9 +170,9 @@ public class LocalMessageSearch implements MessageSearchSpecification {
    public List<Long> getFolderIds() {
        List<Long> results = new ArrayList<>();
        for (SearchConditionTreeNode node : mLeafSet) {
            if (node.mCondition.field == SearchField.FOLDER &&
                    node.mCondition.attribute == SearchAttribute.EQUALS) {
                results.add(Long.valueOf(node.mCondition.value));
            if (node.condition.field == SearchField.FOLDER &&
                    node.condition.attribute == SearchAttribute.EQUALS) {
                results.add(Long.valueOf(node.condition.value));
            }
        }
        return results;
+105 −135
Original line number Diff line number Diff line
package net.thunderbird.feature.search;

import java.util.HashSet;
import java.util.Set;

import android.os.Parcel;
import android.os.Parcelable;

import androidx.annotation.NonNull;
import net.thunderbird.feature.search.api.SearchCondition;
package net.thunderbird.feature.search

import android.os.Parcel
import android.os.Parcelable
import net.thunderbird.feature.search.api.SearchCondition

/**
 * This class stores search conditions. It's basically a boolean expression binary tree.
@@ -17,48 +11,40 @@ import net.thunderbird.feature.search.api.SearchCondition;
 * TODO removing conditions from the tree
 * TODO implement NOT as a node again
 */
public class SearchConditionTreeNode implements Parcelable {

    public enum Operator {
        AND, OR, CONDITION
class SearchConditionTreeNode : Parcelable {
    enum class Operator {
        AND,
        OR,
        CONDITION,
    }

    public SearchConditionTreeNode mLeft;
    public SearchConditionTreeNode mRight;
    public SearchConditionTreeNode mParent;
    @JvmField
    var mLeft: SearchConditionTreeNode? = null

    @JvmField
    var mRight: SearchConditionTreeNode? = null
    var mParent: SearchConditionTreeNode?

    /*
     * If mValue isn't CONDITION then mCondition contains a real
     * condition, otherwise it's null.
     */
    public Operator mValue;
    public SearchCondition mCondition;


    ///////////////////////////////////////////////////////////////
    // Static Helpers to restore a tree from a database cursor
    ///////////////////////////////////////////////////////////////
    @JvmField
    var mValue: Operator
    var condition: SearchCondition?


    ///////////////////////////////////////////////////////////////
    // Constructors
    ///////////////////////////////////////////////////////////////
    public SearchConditionTreeNode(SearchCondition condition) {
        mParent = null;
        mCondition = condition;
        mValue = Operator.CONDITION;
    constructor(condition: SearchCondition?) {
        mParent = null
        this.condition = condition
        mValue = Operator.CONDITION
    }

    public SearchConditionTreeNode(SearchConditionTreeNode parent, Operator op) {
        mParent = parent;
        mValue = op;
        mCondition = null;
    constructor(parent: SearchConditionTreeNode?, op: Operator) {
        mParent = parent
        mValue = op
        this.condition = null
    }


    ///////////////////////////////////////////////////////////////
    // Public modifiers
    ///////////////////////////////////////////////////////////////
    /**
     * Adds the expression as the second argument of an AND
     * clause to this node.
@@ -66,8 +52,8 @@ public class SearchConditionTreeNode implements Parcelable {
     * @param expr Expression to 'AND' with.
     * @ return New top AND node.
     */
    public SearchConditionTreeNode and(SearchConditionTreeNode expr) {
        return add(expr, Operator.AND);
    fun and(expr: SearchConditionTreeNode): SearchConditionTreeNode {
        return add(expr, Operator.AND)
    }

    /**
@@ -78,9 +64,9 @@ public class SearchConditionTreeNode implements Parcelable {
     * @param condition Condition to 'AND' with.
     * @return New top AND node, new root.
     */
    public SearchConditionTreeNode and(SearchCondition condition) {
        SearchConditionTreeNode tmp = new SearchConditionTreeNode(condition);
        return and(tmp);
    fun and(condition: SearchCondition?): SearchConditionTreeNode {
        val tmp = SearchConditionTreeNode(condition)
        return and(tmp)
    }

    /**
@@ -90,8 +76,8 @@ public class SearchConditionTreeNode implements Parcelable {
     * @param expr Expression to 'OR' with.
     * @return New top OR node.
     */
    public SearchConditionTreeNode or(SearchConditionTreeNode expr) {
        return add(expr, Operator.OR);
    fun or(expr: SearchConditionTreeNode): SearchConditionTreeNode {
        return add(expr, Operator.OR)
    }

    /**
@@ -102,36 +88,26 @@ public class SearchConditionTreeNode implements Parcelable {
     * @param condition Condition to 'OR' with.
     * @return New top OR node, new root.
     */
    public SearchConditionTreeNode or(SearchCondition condition) {
        SearchConditionTreeNode tmp = new SearchConditionTreeNode(condition);
        return or(tmp);
    fun or(condition: SearchCondition?): SearchConditionTreeNode {
        val tmp = SearchConditionTreeNode(condition)
        return or(tmp)
    }


    ///////////////////////////////////////////////////////////////
    // Public accessors
    ///////////////////////////////////////////////////////////////
    /**
     * Returns the condition stored in this node.
     * @ return Condition stored in the node.
     */
    public SearchCondition getCondition() {
        return mCondition;
    }

    val leafSet: MutableSet<SearchConditionTreeNode?>
        /**
         * Get a set of all the leaves in the tree.
         * @return Set of all the leaves.
         */
    public Set<SearchConditionTreeNode> getLeafSet() {
        Set<SearchConditionTreeNode> leafSet = new HashSet<>();
        return getLeafSet(leafSet);
        get() {
            val leafSet: MutableSet<SearchConditionTreeNode?> =
                HashSet<SearchConditionTreeNode?>()
            return getLeafSet(leafSet)
        }


    ///////////////////////////////////////////////////////////////
    // Private class logic
    ///////////////////////////////////////////////////////////////
    /**
     * Adds two new ConditionTreeNodes, one for the operator and one for the
     * new condition. The current node will end up on the same level as the
@@ -147,23 +123,21 @@ public class SearchConditionTreeNode implements Parcelable {
     * @ return New parent node, containing the operator .
     * @throws IllegalArgumentException Throws when the provided new node does not have a null parent.
     */
    private SearchConditionTreeNode add(SearchConditionTreeNode node, Operator op) {
        if (node.mParent != null) {
            throw new IllegalArgumentException("Can only add new expressions from root node down.");
        }
    private fun add(node: SearchConditionTreeNode, op: Operator): SearchConditionTreeNode {
        require(node.mParent == null) { "Can only add new expressions from root node down." }

        SearchConditionTreeNode tmpNode = new SearchConditionTreeNode(mParent, op);
        tmpNode.mLeft = this;
        tmpNode.mRight = node;
        val tmpNode = SearchConditionTreeNode(mParent, op)
        tmpNode.mLeft = this
        tmpNode.mRight = node

        if (mParent != null) {
            mParent.updateChild(this, tmpNode);
            mParent!!.updateChild(this, tmpNode)
        }

        this.mParent = tmpNode;
        node.mParent = tmpNode;
        this.mParent = tmpNode
        node.mParent = tmpNode

        return tmpNode;
        return tmpNode
    }

    /**
@@ -174,12 +148,12 @@ public class SearchConditionTreeNode implements Parcelable {
     * @param oldChild Old child node to be replaced.
     * @param newChild New child node.
     */
    private void updateChild(SearchConditionTreeNode oldChild, SearchConditionTreeNode newChild) {
    private fun updateChild(oldChild: SearchConditionTreeNode?, newChild: SearchConditionTreeNode?) {
        // we can compare objects id's because this is the desired behaviour in this case
        if (mLeft == oldChild) {
            mLeft = newChild;
        } else if (mRight == oldChild) {
            mRight = newChild;
        if (mLeft === oldChild) {
            mLeft = newChild
        } else if (mRight === oldChild) {
            mRight = newChild
        }
    }

@@ -190,83 +164,79 @@ public class SearchConditionTreeNode implements Parcelable {
     * @param leafSet Leafset that's being built.
     * @return Set of leaves being completed.
     */
    private Set<SearchConditionTreeNode> getLeafSet(Set<SearchConditionTreeNode> leafSet) {
    private fun getLeafSet(leafSet: MutableSet<SearchConditionTreeNode?>): MutableSet<SearchConditionTreeNode?> {
        if (mLeft == null && mRight == null) {
            // if we ended up in a leaf, add ourself and return
            leafSet.add(this);
            return leafSet;
            leafSet.add(this)
            return leafSet
        }

        // we didn't end up in a leaf
        if (mLeft != null) {
            mLeft.getLeafSet(leafSet);
            mLeft!!.getLeafSet(leafSet)
        }

        if (mRight != null) {
            mRight.getLeafSet(leafSet);
            mRight!!.getLeafSet(leafSet)
        }
        return leafSet;
        return leafSet
    }


    ///////////////////////////////////////////////////////////////
    // Parcelable
    /**/
    // ///////////////////////////////////////////////////////// */ // Parcelable
    //
    // This whole class has to be parcelable because it's passed
    // on through intents.
    ///////////////////////////////////////////////////////////////
    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(mValue.ordinal());
        dest.writeParcelable(mCondition, flags);
        dest.writeParcelable(mLeft, flags);
        dest.writeParcelable(mRight, flags);
    }

    public static final Parcelable.Creator<SearchConditionTreeNode> CREATOR =
            new Parcelable.Creator<SearchConditionTreeNode>() {

        @Override
        public SearchConditionTreeNode createFromParcel(Parcel in) {
            return new SearchConditionTreeNode(in);
    /**/
    // ///////////////////////////////////////////////////////// */
    override fun describeContents(): Int {
        return 0
    }

        @Override
        public SearchConditionTreeNode[] newArray(int size) {
            return new SearchConditionTreeNode[size];
    override fun writeToParcel(dest: Parcel, flags: Int) {
        dest.writeInt(mValue.ordinal)
        dest.writeParcelable(this.condition, flags)
        dest.writeParcelable(mLeft, flags)
        dest.writeParcelable(mRight, flags)
    }
    };

    private SearchConditionTreeNode(Parcel in) {
        mValue = Operator.values()[in.readInt()];
        mCondition = in.readParcelable(SearchConditionTreeNode.class.getClassLoader());
        mLeft = in.readParcelable(SearchConditionTreeNode.class.getClassLoader());
        mRight = in.readParcelable(SearchConditionTreeNode.class.getClassLoader());
        mParent = null;
    private constructor(`in`: Parcel) {
        mValue = Operator.entries[`in`.readInt()]
        this.condition = `in`.readParcelable<SearchCondition?>(SearchConditionTreeNode::class.java.getClassLoader())
        mLeft = `in`.readParcelable<SearchConditionTreeNode?>(SearchConditionTreeNode::class.java.getClassLoader())
        mRight = `in`.readParcelable<SearchConditionTreeNode?>(SearchConditionTreeNode::class.java.getClassLoader())
        mParent = null

        if (mLeft != null) {
            mLeft.mParent = this;
            mLeft!!.mParent = this
        }

        if (mRight != null) {
            mRight.mParent = this;
            mRight!!.mParent = this
        }
    }

    @NonNull
    @Override
    public String toString() {
    override fun toString(): String {
        return "ConditionsTreeNode(" +
            "mLeft=" + mLeft +
            ", mRight=" + mRight +
            ", mParent=" + mParent +
            ", mValue=" + mValue +
            ", mCondition=" + mCondition +
            ')';
            ", mCondition=" + this.condition +
            ')'
    }

    companion object {
        @JvmField
        val CREATOR: Parcelable.Creator<SearchConditionTreeNode?> =
            object : Parcelable.Creator<SearchConditionTreeNode?> {
                override fun createFromParcel(`in`: Parcel): SearchConditionTreeNode {
                    return SearchConditionTreeNode(`in`)
                }

                override fun newArray(size: Int): Array<SearchConditionTreeNode?> {
                    return arrayOfNulls<SearchConditionTreeNode>(size)
                }
            }
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@ public class SqlQueryBuilder {
        }

        if (node.mLeft == null && node.mRight == null) {
            SearchCondition condition = node.mCondition;
            SearchCondition condition = node.condition;
            if (condition.field == SearchField.MESSAGE_CONTENTS) {
                String fulltextQueryString = condition.value;
                if (condition.attribute != SearchAttribute.CONTAINS) {