mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Refactor entry search
This commit is contained in:
@@ -19,25 +19,24 @@
|
||||
*/
|
||||
package com.keepassdroid.database;
|
||||
|
||||
import com.keepassdroid.database.iterator.EntrySearchStringIterator;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.keepassdroid.database.iterator.EntrySearchStringIterator;
|
||||
|
||||
public abstract class EntrySearchHandler extends EntryHandler<PwEntry> {
|
||||
private List<PwEntry> listStorage;
|
||||
private SearchParameters sp;
|
||||
private Date now;
|
||||
|
||||
public static EntrySearchHandler getInstance(PwGroup group, SearchParameters sp, List<PwEntry> listStorage) {
|
||||
if (group instanceof PwGroupV3) {
|
||||
return new EntrySearchHandlerV4(sp, listStorage);
|
||||
if (group instanceof PwGroupV3) { // TODO WTF ?
|
||||
return new EntrySearchHandlerV4(sp, listStorage);
|
||||
} else if (group instanceof PwGroupV4) {
|
||||
return new EntrySearchHandlerV4(sp, listStorage);
|
||||
} else {
|
||||
throw new RuntimeException("Not implemented.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected EntrySearchHandler(SearchParameters sp, List<PwEntry> listStorage) {
|
||||
@@ -75,7 +74,7 @@ public abstract class EntrySearchHandler extends EntryHandler<PwEntry> {
|
||||
groupName = groupName.toLowerCase();
|
||||
}
|
||||
|
||||
if (groupName.indexOf(term) >= 0) {
|
||||
if (groupName.contains(term)) {
|
||||
listStorage.add(entry);
|
||||
return true;
|
||||
}
|
||||
@@ -99,12 +98,12 @@ public abstract class EntrySearchHandler extends EntryHandler<PwEntry> {
|
||||
EntrySearchStringIterator iter = EntrySearchStringIterator.getInstance(entry, sp);
|
||||
while (iter.hasNext()) {
|
||||
String str = iter.next();
|
||||
if (str != null & str.length() > 0) {
|
||||
if (str != null && str.length() > 0) {
|
||||
if (sp.ignoreCase) {
|
||||
str = str.toLowerCase();
|
||||
}
|
||||
|
||||
if (str.indexOf(term) >= 0) {
|
||||
if (str.contains(term)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.keepassdroid.database;
|
||||
|
||||
import com.keepassdroid.utils.StrUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
public class EntrySearchV4 {
|
||||
|
||||
private PwGroupV4 root;
|
||||
|
||||
public EntrySearchV4(PwGroupV4 root) {
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
public void searchEntries(SearchParameters sp, List<PwEntry> listStorage) {
|
||||
if (sp == null) { return; }
|
||||
if (listStorage == null) { return; }
|
||||
|
||||
List<String> terms = StrUtil.splitSearchTerms(sp.searchString);
|
||||
if (terms.size() <= 1 || sp.regularExpression) {
|
||||
searchEntriesSingle(sp, listStorage);
|
||||
return;
|
||||
}
|
||||
|
||||
// Search longest term first
|
||||
Comparator<String> stringLengthComparator = (lhs, rhs) -> lhs.length() - rhs.length();
|
||||
Collections.sort(terms, stringLengthComparator);
|
||||
|
||||
String fullSearch = sp.searchString;
|
||||
List<PwEntry> pg = root.getChildEntries();
|
||||
for (int i = 0; i < terms.size(); i ++) {
|
||||
List<PwEntry> pgNew = new ArrayList<>();
|
||||
|
||||
sp.searchString = terms.get(i);
|
||||
|
||||
boolean negate = false;
|
||||
if (sp.searchString.startsWith("-")) {
|
||||
sp.searchString.substring(1); // TODO Verify bug or no need ?
|
||||
negate = sp.searchString.length() > 0;
|
||||
}
|
||||
|
||||
if (!searchEntriesSingle(sp, pgNew)) {
|
||||
pg = null;
|
||||
break;
|
||||
}
|
||||
|
||||
List<PwEntry> complement = new ArrayList<>();
|
||||
if (negate) {
|
||||
for (PwEntry entry: pg) {
|
||||
if (!pgNew.contains(entry)) {
|
||||
complement.add(entry);
|
||||
}
|
||||
}
|
||||
pg = complement;
|
||||
}
|
||||
else {
|
||||
pg = pgNew;
|
||||
}
|
||||
}
|
||||
|
||||
if (pg != null) {
|
||||
listStorage.addAll(pg);
|
||||
}
|
||||
sp.searchString = fullSearch;
|
||||
|
||||
}
|
||||
|
||||
private boolean searchEntriesSingle(SearchParameters spIn, List<PwEntry> listStorage) {
|
||||
SearchParameters sp = (SearchParameters) spIn.clone();
|
||||
EntryHandler<PwEntry> eh;
|
||||
if (sp.searchString.length() <= 0) {
|
||||
eh = new EntrySearchHandlerAll(sp, listStorage);
|
||||
} else {
|
||||
eh = EntrySearchHandler.getInstance(root, sp, listStorage);
|
||||
}
|
||||
return root.preOrderTraverseTree(null, eh);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -721,7 +721,7 @@ public class PwDatabaseV4 extends PwDatabase {
|
||||
|
||||
PwGroupV4 g = (PwGroupV4) group;
|
||||
|
||||
return g.isSearchEnabled();
|
||||
return g.isSearchingEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -195,7 +195,7 @@ public abstract class PwEntry extends PwNode implements Cloneable {
|
||||
}
|
||||
|
||||
public void touchLocation() { }
|
||||
|
||||
|
||||
public boolean isSearchingEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -508,7 +508,6 @@ public class PwEntryV4 extends PwEntry implements ITimeLogger {
|
||||
@Override
|
||||
public void touch(boolean modified, boolean touchParents) {
|
||||
super.touch(modified, touchParents);
|
||||
|
||||
++usageCount;
|
||||
}
|
||||
|
||||
@@ -519,7 +518,7 @@ public class PwEntryV4 extends PwEntry implements ITimeLogger {
|
||||
|
||||
public boolean isSearchingEnabled() {
|
||||
if (parent != null) {
|
||||
return parent.isSearchEnabled();
|
||||
return parent.isSearchingEnabled();
|
||||
}
|
||||
return PwGroupV4.DEFAULT_SEARCHING_ENABLED;
|
||||
}
|
||||
|
||||
@@ -19,11 +19,7 @@
|
||||
*/
|
||||
package com.keepassdroid.database;
|
||||
|
||||
import com.keepassdroid.utils.StrUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class PwGroup extends PwNode {
|
||||
@@ -150,81 +146,6 @@ public abstract class PwGroup extends PwNode {
|
||||
parent.touch(modified, true);
|
||||
}
|
||||
}
|
||||
|
||||
public void searchEntries(SearchParameters sp, List<PwEntry> listStorage) {
|
||||
if (sp == null) { return; }
|
||||
if (listStorage == null) { return; }
|
||||
|
||||
List<String> terms = StrUtil.splitSearchTerms(sp.searchString);
|
||||
if (terms.size() <= 1 || sp.regularExpression) {
|
||||
searchEntriesSingle(sp, listStorage);
|
||||
return;
|
||||
}
|
||||
|
||||
// Search longest term first
|
||||
Comparator<String> stringLengthComparator = new Comparator<String>() {
|
||||
|
||||
@Override
|
||||
public int compare(String lhs, String rhs) {
|
||||
return lhs.length() - rhs.length();
|
||||
}
|
||||
|
||||
};
|
||||
Collections.sort(terms, stringLengthComparator);
|
||||
|
||||
String fullSearch = sp.searchString;
|
||||
List<PwEntry> pg = this.childEntries;
|
||||
for (int i = 0; i < terms.size(); i ++) {
|
||||
List<PwEntry> pgNew = new ArrayList<PwEntry>();
|
||||
|
||||
sp.searchString = terms.get(i);
|
||||
|
||||
boolean negate = false;
|
||||
if (sp.searchString.startsWith("-")) {
|
||||
sp.searchString.substring(1);
|
||||
negate = sp.searchString.length() > 0;
|
||||
}
|
||||
|
||||
if (!searchEntriesSingle(sp, pgNew)) {
|
||||
pg = null;
|
||||
break;
|
||||
}
|
||||
|
||||
List<PwEntry> complement = new ArrayList<PwEntry>();
|
||||
if (negate) {
|
||||
for (PwEntry entry: pg) {
|
||||
if (!pgNew.contains(entry)) {
|
||||
complement.add(entry);
|
||||
}
|
||||
}
|
||||
pg = complement;
|
||||
}
|
||||
else {
|
||||
pg = pgNew;
|
||||
}
|
||||
}
|
||||
|
||||
if (pg != null) {
|
||||
listStorage.addAll(pg);
|
||||
}
|
||||
sp.searchString = fullSearch;
|
||||
|
||||
}
|
||||
|
||||
private boolean searchEntriesSingle(SearchParameters spIn, List<PwEntry> listStorage) {
|
||||
SearchParameters sp = (SearchParameters) spIn.clone();
|
||||
|
||||
EntryHandler<PwEntry> eh;
|
||||
if (sp.searchString.length() <= 0) {
|
||||
eh = new EntrySearchHandlerAll(sp, listStorage);
|
||||
} else {
|
||||
eh = EntrySearchHandler.getInstance(this, sp, listStorage);
|
||||
}
|
||||
|
||||
if (!preOrderTraverseTree(null, eh)) { return false; }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean preOrderTraverseTree(GroupHandler<PwGroup> groupHandler, EntryHandler<PwEntry> entryHandler) {
|
||||
if (entryHandler != null) {
|
||||
|
||||
@@ -209,14 +209,13 @@ public class PwGroupV4 extends PwGroup implements ITimeLogger {
|
||||
this.lastTopVisibleEntry = lastTopVisibleEntry;
|
||||
}
|
||||
|
||||
public boolean isSearchEnabled() {
|
||||
public boolean isSearchingEnabled() {
|
||||
PwGroupV4 group = this;
|
||||
while (group != null) {
|
||||
Boolean search = group.enableSearching;
|
||||
if (search != null) {
|
||||
return search;
|
||||
}
|
||||
|
||||
group = group.parent;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright 2017 Brian Pellin, Jeremy Jamet / Kunzisoft.
|
||||
*
|
||||
* This file is part of KeePass DX.
|
||||
*
|
||||
* KeePass DX is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* KeePass DX is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.keepassdroid.database;
|
||||
|
||||
public class SearchParametersFactory {
|
||||
public static SearchParameters getNone(PwDatabase db) {
|
||||
SearchParameters sp = getInstance(db);
|
||||
sp.setupNone();
|
||||
|
||||
return sp;
|
||||
}
|
||||
|
||||
public static SearchParameters getInstance(PwDatabase db) {
|
||||
if (db instanceof PwDatabase) {
|
||||
return new SearchParametersV4();
|
||||
}
|
||||
else {
|
||||
return new SearchParameters();
|
||||
}
|
||||
}
|
||||
|
||||
public static SearchParameters getInstance(PwGroup group) {
|
||||
if (group instanceof PwGroupV4) {
|
||||
return new SearchParametersV4();
|
||||
}
|
||||
else {
|
||||
return new SearchParameters();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -295,7 +295,8 @@ public class PwDbV4Output extends PwDbOutput {
|
||||
Stack<PwGroupV4> groupStack = new Stack<PwGroupV4>();
|
||||
groupStack.push(root);
|
||||
|
||||
if (!root.preOrderTraverseTree(new GroupWriter(groupStack), new EntryWriter())) throw new RuntimeException("Writing groups failed");
|
||||
if (!root.preOrderTraverseTree(new GroupWriter(groupStack), new EntryWriter()))
|
||||
throw new RuntimeException("Writing groups failed");
|
||||
|
||||
while (groupStack.size() > 1) {
|
||||
xml.endTag(null, ElemGroup);
|
||||
|
||||
@@ -19,16 +19,16 @@
|
||||
*/
|
||||
package com.keepassdroid.utils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.keepassdroid.database.PwDatabaseV4;
|
||||
import com.keepassdroid.database.PwEntryV4;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class SprContextV4 implements Cloneable {
|
||||
public PwDatabaseV4 db;
|
||||
public PwEntryV4 entry;
|
||||
public Map<String, String> refsCache = new HashMap<String, String>();
|
||||
public Map<String, String> refsCache = new HashMap<>();
|
||||
|
||||
public SprContextV4(PwDatabaseV4 db, PwEntryV4 entry) {
|
||||
this.db = db;
|
||||
|
||||
@@ -19,21 +19,23 @@
|
||||
*/
|
||||
package com.keepassdroid.utils;
|
||||
|
||||
import com.keepassdroid.database.PwDatabase;
|
||||
import com.keepassdroid.database.PwDatabaseV4;
|
||||
import com.keepassdroid.database.PwEntry;
|
||||
import com.keepassdroid.database.PwEntryV4;
|
||||
import com.keepassdroid.database.PwGroupV4;
|
||||
import com.keepassdroid.database.EntrySearchV4;
|
||||
import com.keepassdroid.database.SearchParametersV4;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import com.keepassdroid.database.PwDatabase;
|
||||
import com.keepassdroid.database.PwDatabaseV4;
|
||||
import com.keepassdroid.database.PwEntry;
|
||||
import com.keepassdroid.database.PwEntryV4;
|
||||
import com.keepassdroid.database.SearchParametersV4;
|
||||
|
||||
public class SprEngineV4 {
|
||||
private final int MAX_RECURSION_DEPTH = 12;
|
||||
private final String STR_REF_START = "{REF:";
|
||||
private final String STR_REF_END = "}";
|
||||
private static final int MAX_RECURSION_DEPTH = 12;
|
||||
private static final String STR_REF_START = "{REF:";
|
||||
private static final String STR_REF_END = "}";
|
||||
|
||||
public class TargetResult {
|
||||
public PwEntryV4 entry;
|
||||
@@ -155,7 +157,9 @@ public class SprEngineV4 {
|
||||
else { return null; }
|
||||
|
||||
List<PwEntry> list = new ArrayList<>();
|
||||
ctx.db.getRootGroup().searchEntries(sp, list);
|
||||
// TODO type parameter
|
||||
EntrySearchV4 entrySearchV4 = new EntrySearchV4((PwGroupV4) ctx.db.getRootGroup());
|
||||
entrySearchV4.searchEntries(sp, list);
|
||||
|
||||
if (list.size() > 0) {
|
||||
return new TargetResult((PwEntryV4)list.get(0), wanted);
|
||||
|
||||
Reference in New Issue
Block a user