xref: /haiku/src/apps/haikudepot/packagemodel/DepotInfo.cpp (revision 344ded80d400028c8f561b4b876257b94c12db4a)
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