Skip to content

Commit bcf5160

Browse files
authored
[PR] Merge pull request #58 from CSC207-2022F-UofT/Clean_Architec_Search
Implemented SearchByCommand & Small Changes
2 parents 833987d + bdc8e8f commit bcf5160

File tree

10 files changed

+236
-67
lines changed

10 files changed

+236
-67
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package org.hydev.mcpm.client.commands.entries;
2+
3+
import org.apache.commons.lang3.NotImplementedException;
4+
import org.hydev.mcpm.client.database.boundary.SearchPackagesBoundary;
5+
import org.hydev.mcpm.client.injector.LoadBoundary;
6+
import org.hydev.mcpm.client.injector.PluginNotFoundException;
7+
8+
import java.util.List;
9+
import java.util.function.Consumer;
10+
11+
/**
12+
* Handles the user input for a search.
13+
*/
14+
15+
public class SearchPackagesController {
16+
private final SearchPackagesBoundary searcher;
17+
18+
/**
19+
* Creates a LoadCommand object with this specified LoadBoundary to use when dispatched.
20+
*
21+
* @param searcher The load boundary to use in Command operation.
22+
*/
23+
public SearchPackagesController(SearchPackagesBoundary searcher) {
24+
this.searcher = searcher;
25+
}
26+
27+
28+
/**
29+
* Load plugins and output status to log.
30+
*
31+
* @param pluginNames A list of all plugin names to be loaded.
32+
* @param log Callback for status for log events.
33+
*/
34+
public void searchPackages(List<String> pluginNames, Consumer<String> log) {
35+
throw new NotImplementedException();
36+
}
37+
}

src/main/java/org/hydev/mcpm/client/database/DatabaseInteractor.java

Lines changed: 6 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@
22

33
import org.hydev.mcpm.client.database.boundary.CheckForUpdatesBoundary;
44
import org.hydev.mcpm.client.database.boundary.ListPackagesBoundary;
5-
import org.hydev.mcpm.client.database.boundary.SearchPackagesBoundary;
65
import org.hydev.mcpm.client.database.boundary.MatchPluginsBoundary;
76
import org.hydev.mcpm.client.database.fetcher.DatabaseFetcher;
87
import org.hydev.mcpm.client.database.fetcher.DatabaseFetcherListener;
98
import org.hydev.mcpm.client.database.fetcher.LocalDatabaseFetcher;
109
import org.hydev.mcpm.client.database.fetcher.ProgressBarFetcherListener;
11-
import org.hydev.mcpm.client.database.inputs.*;
10+
import org.hydev.mcpm.client.database.inputs.CheckForUpdatesInput;
11+
import org.hydev.mcpm.client.database.inputs.CheckForUpdatesResult;
12+
import org.hydev.mcpm.client.database.inputs.ListPackagesInput;
1213
import org.hydev.mcpm.client.database.results.ListPackagesResult;
13-
import org.hydev.mcpm.client.database.results.SearchPackagesResult;
14-
import org.hydev.mcpm.client.database.searchusecase.SearcherFactory;
1514

1615
import java.net.URI;
17-
16+
import org.hydev.mcpm.client.database.inputs.MatchPluginsInput;
17+
import org.hydev.mcpm.client.database.inputs.MatchPluginsResult;
1818
import org.hydev.mcpm.client.database.model.PluginModelId;
1919
import org.hydev.mcpm.client.database.model.PluginVersionState;
2020
import org.hydev.mcpm.client.models.PluginModel;
@@ -35,7 +35,7 @@
3535
* @author Jerry Zhu (<a href="https://github.com/jerryzhu509">...</a>)
3636
*/
3737
public class DatabaseInteractor
38-
implements ListPackagesBoundary, SearchPackagesBoundary, MatchPluginsBoundary, CheckForUpdatesBoundary {
38+
implements ListPackagesBoundary, MatchPluginsBoundary, CheckForUpdatesBoundary {
3939
private final DatabaseFetcher fetcher;
4040
private final DatabaseFetcherListener listener;
4141

@@ -107,31 +107,6 @@ public ListPackagesResult list(ListPackagesInput input) {
107107
);
108108
}
109109

110-
/**
111-
* Searches for plugins based on the provided name, keyword, or command.
112-
* The input contains the type of search.
113-
*
114-
* @param input Record of inputs as provided in SearchPackagesInput. See it for more info.
115-
* @return Packages result. See the SearchPackagesResult record for more info.
116-
*/
117-
@Override
118-
public SearchPackagesResult search(SearchPackagesInput input) {
119-
var database = fetcher.fetchDatabase(!input.noCache(), listener);
120-
121-
if (database == null) {
122-
return SearchPackagesResult.by(SearchPackagesResult.State.FAILED_TO_FETCH_DATABASE);
123-
}
124-
125-
var searchStr = input.searchStr().toLowerCase();
126-
if (searchStr.isEmpty())
127-
return SearchPackagesResult.by(SearchPackagesResult.State.INVALID_INPUT);
128-
129-
var plugins = database.plugins();
130-
131-
return new SearchPackagesResult(SearchPackagesResult.State.SUCCESS,
132-
SearcherFactory.createSearcher(input).getSearchList(searchStr, plugins));
133-
}
134-
135110
/**
136111
* Checks for plugin updates.
137112
*
@@ -262,16 +237,6 @@ public static void main(String[] args) {
262237
System.out.println("Result (" + result.pageNumber() + " for " + result.plugins().size() + " plugins):");
263238
System.out.println(formatPluginNames(result.plugins()));
264239

265-
var searchInput = new SearchPackagesInput(SearchPackagesType.BY_NAME, "SkinsRestorer", true);
266-
var result1 = database.search(searchInput);
267-
268-
System.out.println(formatPluginNames(result1.plugins()) + "\n");
269-
270-
var result3 = database.search(new SearchPackagesInput(
271-
SearchPackagesType.BY_KEYWORD, "offline online", true));
272-
273-
System.out.println(formatPluginNames(result3.plugins()));
274-
275240
var matchInput = new MatchPluginsInput(List.of(
276241
PluginModelId.byId(100429),
277242
PluginModelId.byMain("com.gestankbratwurst.smilecore.SmileCore"),

src/main/java/org/hydev/mcpm/client/database/inputs/SearchPackagesInput.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
/**
44
* Input for the SearchPackagesBoundary.
55
*
6-
* @param type An int that specifies the type of search.
7-
* 1 if the search is by name, 2 if the search is by command. Else the search is by keyword.
6+
* @param type Specifies the type of search.
87
* @param searchStr String containing the name, keyword, or command to search by.
98
* @param noCache If true, the ListPackagesBoundary will re-download the database before performing the request.
109
*

src/main/java/org/hydev/mcpm/client/database/results/SearchPackagesResult.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
public record SearchPackagesResult(SearchPackagesResult.State state, List<PluginModel> plugins) {
1515
/**
1616
* The outcome of the SearchPackagesResult.
17+
*
18+
* For INVALID_INPUT, check that your string is non-empty.
1719
*/
1820
public enum State {
1921
SUCCESS,
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package org.hydev.mcpm.client.database.searchusecase;
2+
3+
import org.hydev.mcpm.client.database.boundary.SearchPackagesBoundary;
4+
import org.hydev.mcpm.client.database.fetcher.DatabaseFetcher;
5+
import org.hydev.mcpm.client.database.fetcher.DatabaseFetcherListener;
6+
import org.hydev.mcpm.client.database.fetcher.ProgressBarFetcherListener;
7+
import org.hydev.mcpm.client.database.inputs.SearchPackagesInput;
8+
import org.hydev.mcpm.client.database.results.SearchPackagesResult;
9+
10+
11+
/**
12+
* Handles searching within the database.
13+
*
14+
* @author Jerry Zhu (<a href="https://github.com/jerryzhu509">...</a>)
15+
*/
16+
public class SearchInteractor implements SearchPackagesBoundary {
17+
private final DatabaseFetcher fetcher;
18+
private final DatabaseFetcherListener listener;
19+
20+
21+
/**
22+
* Creates a new database with the provided database fetcher.
23+
* Consider passing LocalDatabaseFetcher. Defaults to the ProgressBarFetcherListener.
24+
*
25+
* @param fetcher The fetcher that will be used to request the database object in boundary calls.
26+
*/
27+
public SearchInteractor(DatabaseFetcher fetcher) {
28+
this(fetcher, new ProgressBarFetcherListener());
29+
}
30+
31+
/**
32+
* Creates a new database with the provided fetcher and upload listener.
33+
*
34+
* @param fetcher The fetcher that will be used to request the database object in boundary calls.
35+
* @param listener The listener that will receive updates if the database is downloaded from the internet.
36+
*/
37+
public SearchInteractor(DatabaseFetcher fetcher, DatabaseFetcherListener listener) {
38+
this.fetcher = fetcher;
39+
this.listener = listener;
40+
}
41+
42+
/**
43+
* Searches for plugins based on the provided name, keyword, or command.
44+
* The input contains the type of search.
45+
*
46+
* @param input Record of inputs as provided in SearchPackagesInput. See it for more info.
47+
* @return Packages result. See the SearchPackagesResult record for more info.
48+
*/
49+
@Override
50+
public SearchPackagesResult search(SearchPackagesInput input) {
51+
var database = fetcher.fetchDatabase(!input.noCache(), listener);
52+
53+
if (database == null) {
54+
return SearchPackagesResult.by(SearchPackagesResult.State.FAILED_TO_FETCH_DATABASE);
55+
}
56+
57+
var searchStr = input.searchStr().toLowerCase();
58+
if (searchStr.isEmpty())
59+
return SearchPackagesResult.by(SearchPackagesResult.State.INVALID_INPUT);
60+
61+
var plugins = database.plugins();
62+
63+
return new SearchPackagesResult(SearchPackagesResult.State.SUCCESS,
64+
SearcherFactory.createSearcher(input).getSearchList(searchStr, plugins));
65+
}
66+
}

src/main/java/org/hydev/mcpm/client/database/searchusecase/Searcher.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,20 @@
1313
public interface Searcher {
1414

1515
/**
16-
* Constructs a dictionary associating a string feature of the plugins to the matching plugins.
16+
* Constructs a dictionary associating a feature (e.g. name, keyword, command)
17+
* of the plugins to the matching plugins.
1718
*
1819
* @param plugins A list of all plugins in the database.
19-
* @return A dictionary associating a string feature of the plugins to the matching plugins.
20+
* @return A dictionary associating a feature of the plugins to the matching plugins.
2021
*/
2122
Map<String, List<PluginModel>> constructSearchMaps(List<PluginModel> plugins);
2223

2324
/**
2425
* Searches for plugins based on the provided user input.
2526
*
26-
* @param inp User input for the search.
27+
* @param inp User input for the search, as a string.
2728
* @param plugins A list of all plugins in the database.
28-
* @return A dictionary associating a string feature of the plugins to the matching plugins.
29+
* @return A list of plugins based on inp.
2930
*/
30-
List<PluginModel> getSearchList(Object inp, List<PluginModel> plugins);
31+
List<PluginModel> getSearchList(String inp, List<PluginModel> plugins);
3132
}

src/main/java/org/hydev/mcpm/client/database/searchusecase/SearcherByCommand.java

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package org.hydev.mcpm.client.database.searchusecase;
22

3-
import org.apache.commons.lang3.NotImplementedException;
43
import org.hydev.mcpm.client.models.PluginModel;
54

6-
import java.util.*;
5+
import java.util.ArrayList;
6+
import java.util.HashMap;
7+
import java.util.List;
8+
import java.util.Map;
79

810
/**
911
* Searcher that returns a map based on commands.
@@ -19,21 +21,41 @@ public class SearcherByCommand implements Searcher {
1921
*
2022
* @param plugins A list of all plugins in the database.
2123
* @return A dictionary associating the command to the matching plugins.
24+
* Returns null if inp is not a string.
2225
*/
2326
@Override
2427
public Map<String, List<PluginModel>> constructSearchMaps(List<PluginModel> plugins) {
25-
throw new NotImplementedException();
28+
Map<String, List<PluginModel>> models = new HashMap<>();
29+
for (PluginModel plugin : plugins) {
30+
// Get latest version
31+
var v = plugin.getLatestPluginVersion();
32+
if (v.isPresent() && v.get().meta() != null && v.get().meta().commands() != null) {
33+
List<String> aliases = v.get().meta()
34+
.commands().keySet().stream()
35+
.map(String::toLowerCase).toList();
36+
for (String alias : aliases) {
37+
if (!models.containsKey(alias.toLowerCase()))
38+
models.put(alias.toLowerCase(), new ArrayList<>());
39+
models.get(alias.toLowerCase()).add(plugin);
40+
}
41+
}
42+
}
43+
return models;
2644
}
2745

2846
/**
29-
* Searches for plugins based on the provided user input.
47+
* Searches for plugins based on the command the user provides.
3048
*
3149
* @param inp User input for the search. Should be a name as a string here.
3250
* @param plugins A list of all plugins in the database.
33-
* @return A dictionary associating a string feature of the plugins to the matching plugins.
51+
* @return A list of plugins based on inp.
3452
*/
3553
@Override
36-
public List<PluginModel> getSearchList(Object inp, List<PluginModel> plugins) {
37-
throw new NotImplementedException();
54+
public List<PluginModel> getSearchList(String inp, List<PluginModel> plugins) {
55+
// Instantiate if null
56+
if (SearcherByCommand.commandMap == null) {
57+
SearcherByCommand.commandMap = constructSearchMaps(plugins);
58+
}
59+
return SearcherByCommand.commandMap.get(inp.toLowerCase());
3860
}
3961
}

src/main/java/org/hydev/mcpm/client/database/searchusecase/SearcherByKeyword.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@
22

33
import org.hydev.mcpm.client.models.PluginModel;
44

5-
import java.util.*;
5+
import java.util.ArrayList;
6+
import java.util.HashMap;
7+
import java.util.List;
8+
import java.util.Map;
9+
import java.util.Set;
10+
import java.util.HashSet;
611

712
/**
813
* Searcher that returns a map based on keywords.
@@ -45,23 +50,20 @@ public Map<String, List<PluginModel>> constructSearchMaps(List<PluginModel> plug
4550
}
4651

4752
/**
48-
* Searches for plugins based on the provided user input.
53+
* Searches for plugins based on the keywords the user provides.
4954
*
5055
* @param inp User input for the search. Should be a name as a non-empty string here.
5156
* @param plugins A list of all plugins in the database.
52-
* @return A dictionary associating a string feature of the plugins to the matching plugins.
53-
* Returns null if inp is not a string.
57+
* @return A list of plugins associated to inp.
5458
*/
5559
@Override
56-
public List<PluginModel> getSearchList(Object inp, List<PluginModel> plugins) {
60+
public List<PluginModel> getSearchList(String inp, List<PluginModel> plugins) {
5761

5862
// Instantiate if null
5963
if (SearcherByKeyword.keywordMap == null) {
6064
SearcherByKeyword.keywordMap = constructSearchMaps(plugins);
6165
}
62-
if (!(inp instanceof String input))
63-
return null;
64-
String [] keywords = input.toLowerCase().split(" "); // Should be a string
66+
String [] keywords = inp.toLowerCase().split(" "); // Should be a string
6567
Set<PluginModel> res = new HashSet<>(SearcherByKeyword.keywordMap.get(keywords[0]));
6668
for (int i = 1; i < keywords.length; i++) {
6769
List<PluginModel> pl = SearcherByKeyword.keywordMap.get(keywords[i]);

src/main/java/org/hydev/mcpm/client/database/searchusecase/SearcherByName.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,11 @@ public Map<String, List<PluginModel>> constructSearchMaps(List<PluginModel> plug
4747
* Returns null if inp is not a string.
4848
*/
4949
@Override
50-
public List<PluginModel> getSearchList(Object inp, List<PluginModel> plugins) {
50+
public List<PluginModel> getSearchList(String inp, List<PluginModel> plugins) {
5151
// Instantiate if null
5252
if (SearcherByName.nameMap == null) {
5353
SearcherByName.nameMap = constructSearchMaps(plugins);
5454
}
55-
if (!(inp instanceof String name))
56-
return null;
57-
return SearcherByName.nameMap.get(name);
55+
return SearcherByName.nameMap.get(inp.toLowerCase());
5856
}
5957
}

0 commit comments

Comments
 (0)