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