1/*
2 * Copyright 2013, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Ingo Weinhold <ingo_weinhold@gmx.de>
7 */
8
9
10#include <package/solver/SolverRepository.h>
11
12#include <package/PackageDefs.h>
13#include <package/PackageRoster.h>
14#include <package/RepositoryCache.h>
15#include <package/RepositoryConfig.h>
16#include <package/solver/SolverPackage.h>
17
18
19static const int32 kInitialPackageListSize = 40;
20
21
22namespace BPackageKit {
23
24
25BSolverRepository::BSolverRepository()
26	:
27	fName(),
28	fPriority(0),
29	fIsInstalled(false),
30	fPackages(kInitialPackageListSize, true),
31	fChangeCount(0)
32{
33}
34
35
36BSolverRepository::BSolverRepository(const BString& name)
37	:
38	fName(),
39	fPriority(0),
40	fIsInstalled(false),
41	fPackages(kInitialPackageListSize, true),
42	fChangeCount(0)
43{
44	SetTo(name);
45}
46
47
48BSolverRepository::BSolverRepository(BPackageInstallationLocation location)
49	:
50	fName(),
51	fPriority(0),
52	fIsInstalled(false),
53	fPackages(kInitialPackageListSize, true),
54	fChangeCount(0)
55{
56	SetTo(location);
57}
58
59
60BSolverRepository::BSolverRepository(BAllInstallationLocations)
61	:
62	fName(),
63	fPriority(0),
64	fIsInstalled(false),
65	fPackages(kInitialPackageListSize, true),
66	fChangeCount(0)
67{
68	SetTo(B_ALL_INSTALLATION_LOCATIONS);
69}
70
71
72BSolverRepository::BSolverRepository(const BRepositoryConfig& config)
73	:
74	fName(),
75	fPriority(0),
76	fIsInstalled(false),
77	fPackages(kInitialPackageListSize, true),
78	fChangeCount(0)
79{
80	SetTo(config);
81}
82
83
84BSolverRepository::~BSolverRepository()
85{
86}
87
88
89status_t
90BSolverRepository::SetTo(const BString& name)
91{
92	Unset();
93
94	fName = name;
95	return fName.IsEmpty() ? B_BAD_VALUE : B_OK;
96}
97
98
99status_t
100BSolverRepository::SetTo(BPackageInstallationLocation location)
101{
102	Unset();
103
104	fName = "Installed";
105
106	status_t error = AddPackages(location);
107	if (error != B_OK) {
108		Unset();
109		return error;
110	}
111
112	fIsInstalled = true;
113	return B_OK;
114}
115
116
117status_t
118BSolverRepository::SetTo(BAllInstallationLocations)
119{
120	status_t error = SetTo(B_PACKAGE_INSTALLATION_LOCATION_SYSTEM);
121	if (error != B_OK)
122		return error;
123
124	error = AddPackages(B_PACKAGE_INSTALLATION_LOCATION_HOME);
125	if (error != B_OK) {
126		Unset();
127		return error;
128	}
129
130	return B_OK;
131}
132
133
134status_t
135BSolverRepository::SetTo(const BRepositoryConfig& config)
136{
137	Unset();
138
139	if (config.InitCheck() != B_OK)
140		return B_BAD_VALUE;
141
142	fName = config.Name();
143	fPriority = config.Priority();
144
145	BPackageRoster roster;
146	BRepositoryCache cache;
147	status_t error = roster.GetRepositoryCache(config.Name(), &cache);
148	if (error != B_OK) {
149		Unset();
150		return error;
151	}
152
153	BRepositoryCache::Iterator it = cache.GetIterator();
154	while (const BPackageInfo* packageInfo = it.Next()) {
155		error = AddPackage(*packageInfo);
156		if (error != B_OK) {
157			Unset();
158			return error;
159		}
160	}
161
162	return B_OK;
163}
164
165
166status_t
167BSolverRepository::SetTo(const BRepositoryCache& cache)
168{
169	Unset();
170
171	const BRepositoryInfo& info = cache.Info();
172	if (info.InitCheck() != B_OK)
173		return B_BAD_VALUE;
174
175	fName = info.Name();
176	fPriority = info.Priority();
177
178	BRepositoryCache::Iterator it = cache.GetIterator();
179	while (const BPackageInfo* packageInfo = it.Next()) {
180		status_t error = AddPackage(*packageInfo);
181		if (error != B_OK) {
182			Unset();
183			return error;
184		}
185	}
186
187	return B_OK;
188}
189
190
191void
192BSolverRepository::Unset()
193{
194	fName = BString();
195	fPriority = 0;
196	fIsInstalled = false;
197	fPackages.MakeEmpty();
198	fChangeCount++;
199}
200
201
202status_t
203BSolverRepository::InitCheck()
204{
205	return fName.IsEmpty() ? B_NO_INIT : B_OK;
206}
207
208
209bool
210BSolverRepository::IsInstalled() const
211{
212	return fIsInstalled;
213}
214
215
216void
217BSolverRepository::SetInstalled(bool isInstalled)
218{
219	fIsInstalled = isInstalled;
220	fChangeCount++;
221}
222
223
224BString
225BSolverRepository::Name() const
226{
227	return fName;
228}
229
230
231int32
232BSolverRepository::Priority() const
233{
234	return fPriority;
235}
236
237
238void
239BSolverRepository::SetPriority(int32 priority)
240{
241	fPriority = priority;
242	fChangeCount++;
243}
244
245
246bool
247BSolverRepository::IsEmpty() const
248{
249	return fPackages.IsEmpty();
250}
251
252
253int32
254BSolverRepository::CountPackages() const
255{
256	return fPackages.CountItems();
257}
258
259
260BSolverPackage*
261BSolverRepository::PackageAt(int32 index) const
262{
263	return fPackages.ItemAt(index);
264}
265
266
267status_t
268BSolverRepository::AddPackage(const BPackageInfo& info,
269	BSolverPackage** _package)
270{
271	BSolverPackage* package = new(std::nothrow) BSolverPackage(this, info);
272	if (package == NULL || !fPackages.AddItem(package)) {
273		delete package;
274		return B_NO_MEMORY;
275	}
276
277	fChangeCount++;
278
279	if (_package != NULL)
280		*_package = package;
281
282	return B_OK;
283}
284
285
286status_t
287BSolverRepository::AddPackages(BPackageInstallationLocation location)
288{
289	BPackageRoster roster;
290	BPackageInfoSet packageInfos;
291	status_t error = roster.GetActivePackages(location, packageInfos);
292	if (error != B_OK)
293		return error;
294
295	BRepositoryCache::Iterator it = packageInfos.GetIterator();
296	while (const BPackageInfo* packageInfo = it.Next()) {
297		error = AddPackage(*packageInfo);
298		if (error != B_OK)
299			return error;
300	}
301
302	return B_OK;
303}
304
305
306bool
307BSolverRepository::RemovePackage(BSolverPackage* package)
308{
309	if (!fPackages.RemoveItem(package, false))
310		return false;
311
312	fChangeCount++;
313	return true;
314}
315
316
317bool
318BSolverRepository::DeletePackage(BSolverPackage* package)
319{
320	if (!RemovePackage(package))
321		return false;
322
323	delete package;
324	return true;
325}
326
327
328uint64
329BSolverRepository::ChangeCount() const
330{
331	return fChangeCount;
332}
333
334
335}	// namespace BPackageKit
336