#include "PackageFilter.h"
#include "Logger.h"
#include "PackageFilterSpecification.h"
#include "PackageUtils.h"
PackageFilter::~PackageFilter()
{
}
void
AndFilter::AddFilter(PackageFilterRef filter)
{
fFilters.push_back(filter);
}
NotFilter::NotFilter(PackageFilterRef filter)
:
fFilter(filter)
{
}
bool
NotFilter::AcceptsPackage(const PackageInfoRef& package) const
{
return !(fFilter.IsSet() && fFilter->AcceptsPackage(package));
}
bool
AndFilter::AcceptsPackage(const PackageInfoRef& package) const
{
std::vector<PackageFilterRef>::const_iterator it;
for (it = fFilters.begin(); it != fFilters.end(); it++) {
PackageFilterRef aFilter = *it;
if (!aFilter.IsSet() || !aFilter->AcceptsPackage(package))
return false;
}
return true;
}
class FalseFilter : public PackageFilter
{
public:
FalseFilter()
{
}
virtual bool AcceptsPackage(const PackageInfoRef& package) const
{
return false;
}
};
class StateFilter : public PackageFilter
{
public:
StateFilter(PackageState state)
:
fState(state)
{
}
virtual bool AcceptsPackage(const PackageInfoRef& package) const
{
return PackageUtils::State(package) == fState;
}
private:
PackageState fState;
};
class CategoryFilter : public PackageFilter {
public:
CategoryFilter(const BString& categoryCode)
:
fCategoryCode(categoryCode)
{
}
virtual bool AcceptsPackage(const PackageInfoRef& package) const
{
if (!package.IsSet())
return false;
PackageClassificationInfoRef classificationInfo = package->PackageClassificationInfo();
if (!classificationInfo.IsSet())
return false;
return classificationInfo->HasCategoryByCode(CategoryCode());
}
const BString& CategoryCode() const
{
return fCategoryCode;
}
private:
BString fCategoryCode;
};
class DepotFilter : public PackageFilter {
public:
DepotFilter(const BString& name)
:
fName(name)
{
}
virtual bool AcceptsPackage(const PackageInfoRef& package) const
{
BString depotName = PackageUtils::DepotName(package);
return !depotName.IsEmpty() && depotName == fName;
}
const BString& Name() const
{
return fName;
}
private:
BString fName;
};
class DesktopFilter : public PackageFilter {
public:
virtual bool AcceptsPackage(const PackageInfoRef& package) const
{
if (!package.IsSet())
return false;
PackageClassificationInfoRef classificationInfo = package->PackageClassificationInfo();
if (!classificationInfo.IsSet())
return false;
return classificationInfo->IsDesktop();
}
};
class NativeDesktopFilter : public PackageFilter {
public:
virtual bool AcceptsPackage(const PackageInfoRef& package) const
{
if (!package.IsSet())
return false;
PackageClassificationInfoRef classificationInfo = package->PackageClassificationInfo();
if (!classificationInfo.IsSet())
return false;
return classificationInfo->IsNativeDesktop();
}
};
class SourceFilter : public PackageFilter {
public:
virtual bool AcceptsPackage(const PackageInfoRef& package) const
{
if (!package.IsSet())
return false;
const BString& packageName = package->Name();
return packageName.EndsWith("_source");
}
};
class DevelopmentFilter : public PackageFilter {
public:
virtual bool AcceptsPackage(const PackageInfoRef& package) const
{
if (!package.IsSet())
return false;
const BString& packageName = package->Name();
return packageName.EndsWith("_devel") || packageName.EndsWith("_debuginfo");
}
};
class SearchTermsFilter : public PackageFilter {
public:
SearchTermsFilter(const BString& searchTerms)
{
int32 index = 0;
while (index < searchTerms.Length()) {
int32 nextSpace = searchTerms.FindFirst(" ", index);
if (nextSpace < 0)
nextSpace = searchTerms.Length();
if (nextSpace > index) {
BString term;
searchTerms.CopyInto(term, index, nextSpace - index);
term.ToLower();
fSearchTerms.Add(term);
}
index = nextSpace + 1;
}
}
virtual bool AcceptsPackage(const PackageInfoRef& package) const
{
if (!package.IsSet())
return false;
for (int32 i = fSearchTerms.CountStrings() - 1; i >= 0; i--) {
const BString& term = fSearchTerms.StringAt(i);
if (package->Name().FindFirst(term) < 0 && !_AcceptsPackageFromPublisher(package, term)
&& !_AcceptsPackageFromLocalizedText(package, term)) {
return false;
}
}
return true;
}
BString SearchTerms() const
{
BString searchTerms;
for (int32 i = 0; i < fSearchTerms.CountStrings(); i++) {
const BString& term = fSearchTerms.StringAt(i);
if (term.IsEmpty())
continue;
if (!searchTerms.IsEmpty())
searchTerms.Append(" ");
searchTerms.Append(term);
}
return searchTerms;
}
private:
bool _TextContains(BString text, const BString& string) const
{
int32 index = text.IFindFirst(string);
return index >= 0;
}
bool _AcceptsPackageFromPublisher(const PackageInfoRef& package,
const BString& searchTerm) const
{
BString publisherName = PackageUtils::PublisherName(package);
return _TextContains(publisherName, searchTerm);
}
bool _AcceptsPackageFromLocalizedText(const PackageInfoRef& package,
const BString& searchTerm) const
{
if (!package.IsSet())
return false;
PackageLocalizedTextRef localizedText = package->LocalizedText();
if (!localizedText.IsSet())
return false;
return _TextContains(localizedText->Title(), searchTerm)
|| _TextContains(localizedText->Summary(), searchTerm)
|| _TextContains(localizedText->Description(), searchTerm);
}
private:
BStringList fSearchTerms;
};
PackageFilterRef
PackageFilterFactory::CreateCategoryFilter(const BString& category)
{
return PackageFilterRef(new CategoryFilter(category), true);
}
PackageFilterRef
PackageFilterFactory::CreateSearchTermsFilter(const BString& searchTerms)
{
return PackageFilterRef(new SearchTermsFilter(searchTerms), true);
}
PackageFilterRef
PackageFilterFactory::CreateDepotFilter(const BString& depotName)
{
return PackageFilterRef(new DepotFilter(depotName), true);
}
PackageFilterRef
PackageFilterFactory::CreateStateFilter(PackageState state)
{
return PackageFilterRef(new StateFilter(state), true);
}
PackageFilterRef
PackageFilterFactory::CreateDesktopFilter()
{
return PackageFilterRef(new DesktopFilter(), true);
}
PackageFilterRef
PackageFilterFactory::CreateNativeDesktopFilter()
{
return PackageFilterRef(new NativeDesktopFilter(), true);
}
PackageFilterRef
PackageFilterFactory::CreateSourceFilter()
{
return PackageFilterRef(new SourceFilter(), true);
}
PackageFilterRef
PackageFilterFactory::CreateDevelopmentFilter()
{
return PackageFilterRef(new DevelopmentFilter(), true);
}
PackageFilterRef
PackageFilterFactory::CreateFalseFilter()
{
return PackageFilterRef(new FalseFilter(), true);
}
PackageFilterRef
PackageFilterFactory::CreateFilter(const PackageFilterSpecificationRef specification)
{
if (!specification.IsSet())
return CreateFalseFilter();
AndFilter* andFilter = new AndFilter();
if (!specification->SearchTerms().IsEmpty())
andFilter->AddFilter(CreateSearchTermsFilter(specification->SearchTerms()));
if (!specification->DepotName().IsEmpty())
andFilter->AddFilter(CreateDepotFilter(specification->DepotName()));
if (!specification->Category().IsEmpty())
andFilter->AddFilter(CreateCategoryFilter(specification->Category()));
if (specification->ShowOnlyDesktopPackages())
andFilter->AddFilter(CreateDesktopFilter());
if (specification->ShowOnlyNativeDesktopPackages())
andFilter->AddFilter(CreateNativeDesktopFilter());
if (!specification->ShowInstalledPackages())
andFilter->AddFilter(PackageFilterRef(new NotFilter(CreateStateFilter(ACTIVATED)), true));
if (!specification->ShowSourcePackages())
andFilter->AddFilter(PackageFilterRef(new NotFilter(CreateSourceFilter()), true));
if (!specification->ShowDevelopPackages())
andFilter->AddFilter(PackageFilterRef(new NotFilter(CreateDevelopmentFilter()), true));
return PackageFilterRef(andFilter, true);
}