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