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