1 /* 2 * Copyright 2013-2014, Stephan Aßmus <superstippi@gmx.de>. 3 * Copyright 2013, Rene Gollent <rene@gollent.com>. 4 * Copyright 2016-2023, Andrew Lindesay <apl@lindesay.co.nz>. 5 * All rights reserved. Distributed under the terms of the MIT License. 6 */ 7 8 9 #include "DepotInfo.h" 10 11 #include <algorithm> 12 13 #include "Logger.h" 14 #include "PackageUtils.h" 15 16 17 // #pragma mark - Sorting Functions 18 19 20 static bool 21 _IsPackageBeforeByName(const PackageInfoRef& p1, const BString& packageName) 22 { 23 return p1->Name().Compare(packageName) < 0; 24 } 25 26 27 /*! This function is used in order to provide an ordering on the packages 28 that are stored on a Depot. 29 */ 30 31 static bool 32 _IsPackageBefore(const PackageInfoRef& p1, const PackageInfoRef& p2) 33 { 34 return _IsPackageBeforeByName(p1, p2->Name()); 35 } 36 37 38 // #pragma mark - Class implementation 39 40 41 DepotInfo::DepotInfo() 42 : 43 fName(), 44 fIdentifier(), 45 fWebAppRepositoryCode() 46 { 47 } 48 49 50 DepotInfo::DepotInfo(const BString& name) 51 : 52 fName(name), 53 fIdentifier(), 54 fWebAppRepositoryCode(), 55 fWebAppRepositorySourceCode() 56 { 57 } 58 59 60 DepotInfo::DepotInfo(const DepotInfo& other) 61 : 62 fName(other.fName), 63 fIdentifier(other.fIdentifier), 64 fPackages(other.fPackages), 65 fWebAppRepositoryCode(other.fWebAppRepositoryCode), 66 fWebAppRepositorySourceCode(other.fWebAppRepositorySourceCode) 67 { 68 } 69 70 71 DepotInfo& 72 DepotInfo::operator=(const DepotInfo& other) 73 { 74 fName = other.fName; 75 fIdentifier = other.fIdentifier; 76 fPackages = other.fPackages; 77 fWebAppRepositoryCode = other.fWebAppRepositoryCode; 78 fWebAppRepositorySourceCode = other.fWebAppRepositorySourceCode; 79 return *this; 80 } 81 82 83 bool 84 DepotInfo::operator==(const DepotInfo& other) const 85 { 86 return fName == other.fName 87 && fIdentifier == fIdentifier 88 && fPackages == other.fPackages; 89 } 90 91 92 bool 93 DepotInfo::operator!=(const DepotInfo& other) const 94 { 95 return !(*this == other); 96 } 97 98 99 int32 100 DepotInfo::CountPackages() const 101 { 102 return fPackages.size(); 103 } 104 105 106 PackageInfoRef 107 DepotInfo::PackageAtIndex(int32 index) 108 { 109 return fPackages[index]; 110 } 111 112 113 /*! This method will insert the package into the list of packages 114 in order so that the list of packages remains in order. 115 */ 116 117 void 118 DepotInfo::AddPackage(PackageInfoRef& package) 119 { 120 std::vector<PackageInfoRef>::iterator itInsertionPt 121 = std::lower_bound( 122 fPackages.begin(), 123 fPackages.end(), 124 package, 125 &_IsPackageBefore); 126 if (fPackages.end() != itInsertionPt && (*itInsertionPt)->Name() == package->Name()) 127 *itInsertionPt = package; 128 else 129 fPackages.insert(itInsertionPt, package); 130 } 131 132 133 bool 134 DepotInfo::HasPackage(const BString& packageName) 135 { 136 std::vector<PackageInfoRef>::const_iterator it 137 = std::lower_bound( 138 fPackages.begin(), 139 fPackages.end(), 140 packageName, 141 &_IsPackageBeforeByName); 142 if (it != fPackages.end()) { 143 PackageInfoRef candidate = *it; 144 return (candidate.Get() != NULL 145 && candidate.Get()->Name() == packageName); 146 } 147 return false; 148 } 149 150 151 PackageInfoRef 152 DepotInfo::PackageByName(const BString& packageName) 153 { 154 std::vector<PackageInfoRef>::const_iterator it 155 = std::lower_bound( 156 fPackages.begin(), 157 fPackages.end(), 158 packageName, 159 &_IsPackageBeforeByName); 160 161 if (it != fPackages.end()) { 162 PackageInfoRef candidate = *it; 163 if (candidate.Get() != NULL && candidate.Get()->Name() == packageName) 164 return candidate; 165 } 166 return PackageInfoRef(); 167 } 168 169 170 void 171 DepotInfo::SyncPackagesFromDepot(const DepotInfoRef& other) 172 { 173 for (int32 i = other->CountPackages() - 1; i >= 0; i--) { 174 PackageInfoRef otherPackage = other->PackageAtIndex(i); 175 PackageInfoRef myPackage = PackageByName(otherPackage->Name()); 176 177 if (myPackage.IsSet()) { 178 PackageLocalInfoRef localInfo = PackageUtils::NewLocalInfo(myPackage); 179 PackageLocalInfoRef otherLocalInfo = otherPackage->LocalInfo(); 180 181 if (otherLocalInfo.IsSet()) { 182 localInfo->SetState(otherLocalInfo->State()); 183 localInfo->SetLocalFilePath(otherLocalInfo->LocalFilePath()); 184 localInfo->SetSystemDependency(otherLocalInfo->IsSystemDependency()); 185 } 186 187 myPackage->SetLocalInfo(localInfo); 188 } else { 189 HDINFO("%s: new package: '%s'", fName.String(), 190 otherPackage->Name().String()); 191 AddPackage(otherPackage); 192 } 193 } 194 195 for (int32 i = CountPackages() - 1; i >= 0; i--) { 196 PackageInfoRef myPackage = PackageAtIndex(i); 197 if (!other->HasPackage(myPackage->Name())) { 198 HDINFO("%s: removing package: '%s'", fName.String(), 199 myPackage->Name().String()); 200 fPackages.erase(fPackages.begin() + i); 201 } 202 } 203 } 204 205 206 bool 207 DepotInfo::HasAnyProminentPackages() const 208 { 209 std::vector<PackageInfoRef>::const_iterator it; 210 for (it = fPackages.begin(); it != fPackages.end(); it++) { 211 const PackageInfoRef& package = *it; 212 const PackageClassificationInfoRef& classification = package->PackageClassificationInfo(); 213 214 if (classification.IsSet()) { 215 if (classification->IsProminent()) 216 return true; 217 } 218 } 219 return false; 220 } 221 222 223 void 224 DepotInfo::SetIdentifier(const BString& value) 225 { 226 fIdentifier = value; 227 } 228 229 230 void 231 DepotInfo::SetWebAppRepositoryCode(const BString& code) 232 { 233 fWebAppRepositoryCode = code; 234 } 235 236 237 void 238 DepotInfo::SetWebAppRepositorySourceCode(const BString& code) 239 { 240 fWebAppRepositorySourceCode = code; 241 } 242