1/*
2 * Copyright 2019, Andrew Lindesay <apl@lindesay.co.nz>.
3 *
4 * All rights reserved. Distributed under the terms of the MIT License.
5 */
6#include "ValidationFailure.h"
7
8// These are keys that are used to store this object's data into a BMessage
9// instance.
10
11#define KEY_PROPERTY							"property"
12#define KEY_PREFIX_MESSAGE						"message_"
13#define KEY_PREFIX_ITEM							"item_"
14
15
16// #pragma mark - Single Validation Failure
17
18
19ValidationFailure::ValidationFailure(BMessage* from)
20{
21	from->FindString(KEY_PROPERTY, &fProperty);
22
23	if (fProperty.IsEmpty())
24		debugger("illegal state; missing property in message");
25
26	status_t result = B_OK;
27	BString name;
28	BString message;
29
30	for (int32 i = 0; result == B_OK; i++) {
31		name.SetToFormat("%s%" B_PRId32, KEY_PREFIX_MESSAGE, i);
32		result = from->FindString(name, &message);
33
34		if (result == B_OK)
35			AddMessage(message);
36	}
37}
38
39
40ValidationFailure::ValidationFailure(const BString& property)
41{
42	fProperty = property;
43}
44
45
46ValidationFailure::~ValidationFailure()
47{
48}
49
50
51const BString&
52ValidationFailure::Property() const
53{
54	return fProperty;
55}
56
57
58const BStringList&
59ValidationFailure::Messages() const
60{
61	return fMessages;
62}
63
64
65bool
66ValidationFailure::IsEmpty() const
67{
68	return fMessages.IsEmpty();
69}
70
71
72bool
73ValidationFailure::Contains(const BString& message) const
74{
75	return fMessages.HasString(message);
76}
77
78
79void
80ValidationFailure::AddMessage(const BString& value)
81{
82	fMessages.Add(value);
83}
84
85
86status_t
87ValidationFailure::Archive(BMessage* into, bool deep) const
88{
89	status_t result = B_OK;
90	BString key;
91	if (result == B_OK)
92		result = into->AddString(KEY_PROPERTY, fProperty);
93	for (int32 i = 0; result == B_OK && i < fMessages.CountStrings(); i++) {
94		key.SetToFormat("%s%" B_PRId32, KEY_PREFIX_MESSAGE, i);
95		result = into->AddString(key, fMessages.StringAt(i));
96	}
97	return result;
98}
99
100
101// #pragma mark - Collections of Validation Failures
102
103
104ValidationFailures::ValidationFailures(BMessage* from)
105	:
106	fItems(20, true)
107{
108	_AddFromMessage(from);
109}
110
111
112ValidationFailures::ValidationFailures()
113	:
114	fItems(20, true)
115{
116}
117
118
119ValidationFailures::~ValidationFailures()
120{
121}
122
123
124void
125ValidationFailures::AddFailure(const BString& property, const BString& message)
126{
127	_GetOrCreateFailure(property)->AddMessage(message);
128}
129
130
131int32
132ValidationFailures::CountFailures() const
133{
134	return fItems.CountItems();
135}
136
137
138bool
139ValidationFailures::IsEmpty() const
140{
141	return fItems.IsEmpty();
142}
143
144
145bool
146ValidationFailures::Contains(const BString& property) const
147{
148	ValidationFailure* failure = _GetFailure(property);
149	return failure != NULL && !failure->IsEmpty();
150}
151
152
153bool
154ValidationFailures::Contains(const BString& property,
155	const BString& message) const
156{
157	ValidationFailure* failure = _GetFailure(property);
158	return failure != NULL && failure->Contains(message);
159}
160
161
162ValidationFailure*
163ValidationFailures::FailureAtIndex(int32 index) const
164{
165	return fItems.ItemAt(index);
166}
167
168
169status_t
170ValidationFailures::Archive(BMessage* into, bool deep) const
171{
172	status_t result = B_OK;
173	BString key;
174
175	for (int32 i = 0; i < fItems.CountItems() && result == B_OK; i++) {
176		ValidationFailure* item = fItems.ItemAt(i);
177		BMessage itemMessage;
178		result = item->Archive(&itemMessage);
179		if (result == B_OK) {
180			key.SetToFormat("%s%" B_PRId32, KEY_PREFIX_ITEM, i);
181			result = into->AddMessage(key, &itemMessage);
182		}
183	}
184
185	return result;
186}
187
188
189ValidationFailure*
190ValidationFailures::_GetFailure(const BString& property) const
191{
192	for (int32 i = 0; i < fItems.CountItems(); i++) {
193		ValidationFailure* item = fItems.ItemAt(i);
194		if (item->Property() == property)
195			return item;
196	}
197
198	return NULL;
199}
200
201
202ValidationFailure*
203ValidationFailures::_GetOrCreateFailure(const BString& property)
204{
205	ValidationFailure* item = _GetFailure(property);
206
207	if (item == NULL) {
208		item = new ValidationFailure(property);
209		fItems.AddItem(item);
210	}
211
212	return item;
213}
214
215
216void
217ValidationFailures::_AddFromMessage(const BMessage* from)
218{
219	int32 i = 0;
220	BString key;
221
222	while (true) {
223		BMessage itemMessage;
224		key.SetToFormat("%s%" B_PRId32, KEY_PREFIX_ITEM, i);
225		if (from->FindMessage(key, &itemMessage) != B_OK)
226			return;
227		fItems.AddItem(new ValidationFailure(&itemMessage));
228		i++;
229	}
230}
231