Loading feature/search/src/main/java/net/thunderbird/feature/search/LocalMessageSearch.java +3 −3 Original line number Diff line number Diff line Loading @@ -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; Loading feature/search/src/main/java/net/thunderbird/feature/search/SearchConditionTreeNode.kt +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. Loading @@ -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. Loading @@ -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) } /** Loading @@ -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) } /** Loading @@ -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) } /** Loading @@ -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 Loading @@ -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 } /** Loading @@ -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 } } Loading @@ -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) } } } } legacy/core/src/main/java/com/fsck/k9/search/SqlQueryBuilder.java +1 −1 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading
feature/search/src/main/java/net/thunderbird/feature/search/LocalMessageSearch.java +3 −3 Original line number Diff line number Diff line Loading @@ -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; Loading
feature/search/src/main/java/net/thunderbird/feature/search/SearchConditionTreeNode.kt +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. Loading @@ -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. Loading @@ -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) } /** Loading @@ -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) } /** Loading @@ -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) } /** Loading @@ -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 Loading @@ -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 } /** Loading @@ -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 } } Loading @@ -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) } } } }
legacy/core/src/main/java/com/fsck/k9/search/SqlQueryBuilder.java +1 −1 Original line number Diff line number Diff line Loading @@ -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) { Loading