NewPipeExtractor/extractor/src/main/java/org/schabi/newpipe/extractor/search/filter/FilterGroup.java

187 lines
6.1 KiB
Java

// Created by evermind-zz 2022, licensed GNU GPL version 3 or later
package org.schabi.newpipe.extractor.search.filter;
import java.util.HashMap;
import java.util.Map;
/**
* This class represents a filter category/group. For example 'Sort order'.
* <p>
* Its main purpose is to host a bunch of {@link FilterItem}s that belong to that
* group. Eg. 'Relevance', 'Views', 'Rating'
*/
public final class FilterGroup {
/**
* {@link #getIdentifier()}
*/
private final int identifier;
/**
* The name of the filter group that the user will see
*/
private final String groupName;
/**
* Specify whether only one item can be selected in this group at a time.
*/
private final boolean onlyOneCheckable;
/**
* Each group may have a default value that should be selected.
* <p>
* It should be set to the the {@link FilterItem}'s id. If there is no default option
* it should be set to {@link FilterContainer#ITEM_IDENTIFIER_UNKNOWN}
*/
private final int defaultSelectedFilterId;
/**
* The filter items that belong to this {@link FilterGroup}.
*/
private final FilterItem[] filterItems;
/**
* {@link #getAllSortFilters()}.
*/
private final FilterContainer allSortFilters;
private FilterGroup(final int identifier,
final String groupName,
final boolean onlyOneCheckable,
final int defaultSelectedFilterId,
final FilterItem[] filterItems,
final FilterContainer allSortFilters) {
this.identifier = identifier;
this.groupName = groupName;
this.onlyOneCheckable = onlyOneCheckable;
this.defaultSelectedFilterId = defaultSelectedFilterId;
this.filterItems = filterItems;
this.allSortFilters = allSortFilters;
}
/**
* If this group is a content filter and has corresponding sort filters, this
* {@link FilterContainer} contains all available sort filters for this group.
*
* @return may be null as not all {@link FilterGroup}s have sort filters.
*/
public FilterContainer getAllSortFilters() {
return allSortFilters;
}
/**
* {@link FilterItem#getIdentifier()}
*/
public int getIdentifier() {
return this.identifier;
}
/**
* {@link #groupName}
*/
public String getName() {
return groupName;
}
/**
* {@link #defaultSelectedFilterId}
*/
public int getDefaultSelectedFilterId() {
return defaultSelectedFilterId;
}
/**
* {@link #filterItems}
*/
public FilterItem[] getFilterItems() {
return filterItems;
}
/**
* {@link #onlyOneCheckable}
*/
public boolean isOnlyOneCheckable() {
return onlyOneCheckable;
}
/**
* Factory for building {@link FilterGroup}s.
* <p>
* Each service should only have one instance.
* This is implemented in {@link BaseSearchFilters}
*/
public static class Factory {
/**
* A map that has all {@link FilterItem}s that are relevant for one service. Eg. Youtube
*/
public final Map<Integer, FilterItem> filtersMap = new HashMap<>();
/**
* Check if a {@link FilterItem} has a unique id.
*
* @param filterItems a map with the previously added {@link FilterItem}'s to compare with.
* @param item the new {@link FilterItem} that should be added.
*/
void uniqueIdChecker(final Map<Integer, FilterItem> filterItems,
final FilterItem item) {
if (item.getIdentifier() == FilterContainer.ITEM_IDENTIFIER_UNKNOWN
&& !(item instanceof FilterItem.DividerItem)) {
throw new InvalidFilterIdException("Filter ID "
+ item.getIdentifier() + " aka FilterContainer.ITEM_IDENTIFIER_UNKNOWN"
+ " for \"" + item.getName() + "\" not allowed");
}
if (filterItems.containsKey(item.getIdentifier())) {
final FilterItem storedItem = filterItems.get(item.getIdentifier());
throw new InvalidFilterIdException("Filter ID "
+ item.getIdentifier() + " for \"" + item.getName()
+ "\" already taken from \"" + storedItem.getName() + "\"");
}
}
/**
* Add a new {@link FilterItem} that is relevant to this service.
* <p>
* The {@link FilterItem}s are accessible by their id via {@link #getFilterForId(int)}
*
* @param filter the new {@link FilterItem} to be added to the factory.
* @return the identifier of the {@link FilterItem}
*/
public int addFilterItem(final FilterItem filter) {
uniqueIdChecker(filtersMap, filter);
filtersMap.put(filter.getIdentifier(), filter);
return filter.getIdentifier();
}
public FilterGroup createFilterGroup(final int identifier,
final String groupName,
final boolean onlyOneCheckable,
final int defaultSelectedFilterId,
final FilterItem[] filterItems,
final FilterContainer allSortFilters) {
return new FilterGroup(identifier, groupName, onlyOneCheckable,
defaultSelectedFilterId, filterItems, allSortFilters);
}
/**
* Get previously via {@link #addFilterItem(FilterItem)} added {@link FilterItem}.
*
* @param identifier the id of the desired {@link FilterItem}
* @return the desired {@link FilterItem}
*/
public FilterItem getFilterForId(final int identifier) {
return filtersMap.get(identifier);
}
private static class InvalidFilterIdException extends RuntimeException {
InvalidFilterIdException(final String message) {
super(message);
}
}
}
}