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
ValidationFailure(BMessage * from)19 ValidationFailure::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
ValidationFailure(const BString & property)40 ValidationFailure::ValidationFailure(const BString& property)
41 {
42 fProperty = property;
43 }
44
45
~ValidationFailure()46 ValidationFailure::~ValidationFailure()
47 {
48 }
49
50
51 const BString&
Property() const52 ValidationFailure::Property() const
53 {
54 return fProperty;
55 }
56
57
58 const BStringList&
Messages() const59 ValidationFailure::Messages() const
60 {
61 return fMessages;
62 }
63
64
65 bool
IsEmpty() const66 ValidationFailure::IsEmpty() const
67 {
68 return fMessages.IsEmpty();
69 }
70
71
72 bool
Contains(const BString & message) const73 ValidationFailure::Contains(const BString& message) const
74 {
75 return fMessages.HasString(message);
76 }
77
78
79 void
AddMessage(const BString & value)80 ValidationFailure::AddMessage(const BString& value)
81 {
82 fMessages.Add(value);
83 }
84
85
86 status_t
Archive(BMessage * into,bool deep) const87 ValidationFailure::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
ValidationFailures(BMessage * from)104 ValidationFailures::ValidationFailures(BMessage* from)
105 :
106 fItems(20, true)
107 {
108 _AddFromMessage(from);
109 }
110
111
ValidationFailures()112 ValidationFailures::ValidationFailures()
113 :
114 fItems(20, true)
115 {
116 }
117
118
~ValidationFailures()119 ValidationFailures::~ValidationFailures()
120 {
121 }
122
123
124 void
AddFailure(const BString & property,const BString & message)125 ValidationFailures::AddFailure(const BString& property, const BString& message)
126 {
127 _GetOrCreateFailure(property)->AddMessage(message);
128 }
129
130
131 int32
CountFailures() const132 ValidationFailures::CountFailures() const
133 {
134 return fItems.CountItems();
135 }
136
137
138 bool
IsEmpty() const139 ValidationFailures::IsEmpty() const
140 {
141 return fItems.IsEmpty();
142 }
143
144
145 bool
Contains(const BString & property) const146 ValidationFailures::Contains(const BString& property) const
147 {
148 ValidationFailure* failure = _GetFailure(property);
149 return failure != NULL && !failure->IsEmpty();
150 }
151
152
153 bool
Contains(const BString & property,const BString & message) const154 ValidationFailures::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
162 ValidationFailure*
FailureAtIndex(int32 index) const163 ValidationFailures::FailureAtIndex(int32 index) const
164 {
165 return fItems.ItemAt(index);
166 }
167
168
169 status_t
Archive(BMessage * into,bool deep) const170 ValidationFailures::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
189 ValidationFailure*
_GetFailure(const BString & property) const190 ValidationFailures::_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
202 ValidationFailure*
_GetOrCreateFailure(const BString & property)203 ValidationFailures::_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
216 void
_AddFromMessage(const BMessage * from)217 ValidationFailures::_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