1 // Created on: 2017-06-26
2 // Created by: Andrey Betenev
3 // Copyright (c) 2017 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <Message_Report.hxx>
17
18 #include <Message.hxx>
19 #include <Message_AlertExtended.hxx>
20 #include <Message_AttributeMeter.hxx>
21 #include <Message_Attribute.hxx>
22 #include <Message_CompositeAlerts.hxx>
23 #include <Message_Msg.hxx>
24 #include <Message_Messenger.hxx>
25 #include <Message_PrinterToReport.hxx>
26
27 #include <Precision.hxx>
28 #include <Standard_Dump.hxx>
29
IMPLEMENT_STANDARD_RTTIEXT(Message_Report,Standard_Transient)30 IMPLEMENT_STANDARD_RTTIEXT(Message_Report,Standard_Transient)
31
32 //=======================================================================
33 //function : Message_Report
34 //purpose :
35 //=======================================================================
36
37 Message_Report::Message_Report ()
38 : myLimit (-1),
39 myIsActiveInMessenger (Standard_False)
40 {
41 }
42
43 //=======================================================================
44 //function : AddAlert
45 //purpose :
46 //=======================================================================
47
AddAlert(Message_Gravity theGravity,const Handle (Message_Alert)& theAlert)48 void Message_Report::AddAlert (Message_Gravity theGravity, const Handle(Message_Alert)& theAlert)
49 {
50 Standard_Mutex::Sentry aSentry (myMutex);
51
52 // alerts of the top level
53 if (myAlertLevels.IsEmpty())
54 {
55 Handle (Message_CompositeAlerts) aCompositeAlert = compositeAlerts (Standard_True);
56 if (aCompositeAlert->AddAlert (theGravity, theAlert))
57 {
58 return;
59 }
60
61 // remove alerts under the report only
62 const Message_ListOfAlert& anAlerts = aCompositeAlert->Alerts (theGravity);
63 if (anAlerts.Extent() > myLimit)
64 {
65 aCompositeAlert->RemoveAlert (theGravity, anAlerts.First());
66 }
67 return;
68 }
69
70 // if there are some levels of alerts, the new alert will be placed below the root
71 myAlertLevels.Last()->AddAlert (theGravity, theAlert);
72 }
73
74 //=======================================================================
75 //function : GetAlerts
76 //purpose :
77 //=======================================================================
78
GetAlerts(Message_Gravity theGravity) const79 const Message_ListOfAlert& Message_Report::GetAlerts (Message_Gravity theGravity) const
80 {
81 static const Message_ListOfAlert anEmptyList;
82 if (myCompositAlerts.IsNull())
83 {
84 return anEmptyList;
85 }
86 return myCompositAlerts->Alerts (theGravity);
87 }
88
89 //=======================================================================
90 //function : HasAlert
91 //purpose :
92 //=======================================================================
93
HasAlert(const Handle (Standard_Type)& theType)94 Standard_Boolean Message_Report::HasAlert (const Handle(Standard_Type)& theType)
95 {
96 for (int iGravity = Message_Trace; iGravity <= Message_Fail; ++iGravity)
97 {
98 if (HasAlert (theType, (Message_Gravity)iGravity))
99 return Standard_True;
100 }
101 return Standard_False;
102 }
103
104 //=======================================================================
105 //function : HasAlert
106 //purpose :
107 //=======================================================================
108
HasAlert(const Handle (Standard_Type)& theType,Message_Gravity theGravity)109 Standard_Boolean Message_Report::HasAlert (const Handle(Standard_Type)& theType, Message_Gravity theGravity)
110 {
111 if (compositeAlerts().IsNull())
112 {
113 return Standard_False;
114 }
115
116 return compositeAlerts()->HasAlert (theType, theGravity);
117 }
118
119 //=======================================================================
120 //function : IsActiveInMessenger
121 //purpose :
122 //=======================================================================
IsActiveInMessenger(const Handle (Message_Messenger)&) const123 Standard_Boolean Message_Report::IsActiveInMessenger (const Handle(Message_Messenger)&) const
124 {
125 return myIsActiveInMessenger;
126 }
127
128 //=======================================================================
129 //function : ActivateInMessenger
130 //purpose :
131 //=======================================================================
ActivateInMessenger(const Standard_Boolean toActivate,const Handle (Message_Messenger)& theMessenger)132 void Message_Report::ActivateInMessenger (const Standard_Boolean toActivate,
133 const Handle(Message_Messenger)& theMessenger)
134 {
135 if (toActivate == IsActiveInMessenger())
136 return;
137
138 myIsActiveInMessenger = toActivate;
139 Handle(Message_Messenger) aMessenger = theMessenger.IsNull() ? Message::DefaultMessenger() : theMessenger;
140 if (toActivate)
141 {
142 Handle (Message_PrinterToReport) aPrinterToReport = new Message_PrinterToReport();
143 aPrinterToReport->SetReport (this);
144 aMessenger->AddPrinter (aPrinterToReport);
145 }
146 else // deactivate
147 {
148 Message_SequenceOfPrinters aPrintersToRemove;
149 for (Message_SequenceOfPrinters::Iterator anIterator (aMessenger->Printers()); anIterator.More(); anIterator.Next())
150 {
151 const Handle(Message_Printer) aPrinter = anIterator.Value();
152 if (aPrinter->IsKind(STANDARD_TYPE (Message_PrinterToReport)) &&
153 Handle(Message_PrinterToReport)::DownCast (aPrinter)->Report() == this)
154 aPrintersToRemove.Append (aPrinter);
155 }
156 for (Message_SequenceOfPrinters::Iterator anIterator (aPrintersToRemove); anIterator.More(); anIterator.Next())
157 {
158 aMessenger->RemovePrinter (anIterator.Value());
159 }
160 }
161 }
162
163 //=======================================================================
164 //function : UpdateActiveInMessenger
165 //purpose :
166 //=======================================================================
UpdateActiveInMessenger(const Handle (Message_Messenger)& theMessenger)167 void Message_Report::UpdateActiveInMessenger (const Handle(Message_Messenger)& theMessenger)
168 {
169 Handle(Message_Messenger) aMessenger = theMessenger.IsNull() ? Message::DefaultMessenger() : theMessenger;
170 for (Message_SequenceOfPrinters::Iterator anIterator (aMessenger->Printers()); anIterator.More(); anIterator.Next())
171 {
172 if (anIterator.Value()->IsKind(STANDARD_TYPE (Message_PrinterToReport)) &&
173 Handle(Message_PrinterToReport)::DownCast (anIterator.Value())->Report() == this)
174 {
175 myIsActiveInMessenger = Standard_True;
176 return;
177 }
178 }
179 myIsActiveInMessenger = Standard_False;
180 }
181
182 //=======================================================================
183 //function : AddLevel
184 //purpose :
185 //=======================================================================
AddLevel(Message_Level * theLevel,const TCollection_AsciiString & theName)186 void Message_Report::AddLevel (Message_Level* theLevel, const TCollection_AsciiString& theName)
187 {
188 Standard_Mutex::Sentry aSentry (myMutex);
189
190 myAlertLevels.Append (theLevel);
191
192 Handle(Message_AlertExtended) aLevelRootAlert = new Message_AlertExtended();
193
194 Handle(Message_Attribute) anAttribute;
195 if (!ActiveMetrics().IsEmpty())
196 {
197 anAttribute = new Message_AttributeMeter (theName);
198 }
199 else
200 {
201 anAttribute = new Message_Attribute (theName);
202 }
203 aLevelRootAlert->SetAttribute (anAttribute);
204 theLevel->SetRootAlert (aLevelRootAlert, myAlertLevels.Size() == 1);
205
206 if (myAlertLevels.Size() == 1) // this is the first level, so root alert should be pushed in the report composite of alerts
207 {
208 compositeAlerts (Standard_True)->AddAlert (Message_Info, theLevel->RootAlert());
209 }
210 if (myAlertLevels.Size() > 1) // this is the first level, so root alert should be pushed in the report composite of alerts
211 {
212 // root alert of next levels should be pushed under the previous level
213 Message_Level* aPrevLevel = myAlertLevels.Value (myAlertLevels.Size() - 1); // previous level
214 aPrevLevel->AddAlert (Message_Info, aLevelRootAlert);
215 }
216 }
217
218 //=======================================================================
219 //function : RemoveLevel
220 //purpose :
221 //=======================================================================
222
RemoveLevel(Message_Level * theLevel)223 void Message_Report::RemoveLevel (Message_Level* theLevel)
224 {
225 Standard_Mutex::Sentry aSentry (myMutex);
226
227 for (int aLevelIndex = myAlertLevels.Size(); aLevelIndex >= 1; aLevelIndex--)
228 {
229 Message_Level* aLevel = myAlertLevels.Value (aLevelIndex);
230 Message_AttributeMeter::StopAlert (aLevel->RootAlert());
231
232 myAlertLevels.Remove (aLevelIndex);
233 if (aLevel == theLevel)
234 {
235 return;
236 }
237 }
238 }
239
240 //=======================================================================
241 //function : Clear
242 //purpose :
243 //=======================================================================
Clear()244 void Message_Report::Clear()
245 {
246 if (compositeAlerts().IsNull())
247 {
248 return;
249 }
250
251 Standard_Mutex::Sentry aSentry (myMutex);
252
253 compositeAlerts()->Clear();
254 myAlertLevels.Clear();
255 }
256
257 //=======================================================================
258 //function : Clear
259 //purpose :
260 //=======================================================================
Clear(Message_Gravity theGravity)261 void Message_Report::Clear (Message_Gravity theGravity)
262 {
263 if (compositeAlerts().IsNull())
264 {
265 return;
266 }
267
268 Standard_Mutex::Sentry aSentry (myMutex);
269
270 compositeAlerts()->Clear (theGravity);
271 myAlertLevels.Clear();
272 }
273
274 //=======================================================================
275 //function : Clear
276 //purpose :
277 //=======================================================================
Clear(const Handle (Standard_Type)& theType)278 void Message_Report::Clear (const Handle(Standard_Type)& theType)
279 {
280 if (compositeAlerts().IsNull())
281 {
282 return;
283 }
284
285 Standard_Mutex::Sentry aSentry (myMutex);
286
287 compositeAlerts()->Clear (theType);
288 myAlertLevels.Clear();
289 }
290
291 //=======================================================================
292 //function : SetActiveMetric
293 //purpose :
294 //=======================================================================
SetActiveMetric(const Message_MetricType theMetricType,const Standard_Boolean theActivate)295 void Message_Report::SetActiveMetric (const Message_MetricType theMetricType,
296 const Standard_Boolean theActivate)
297 {
298 if (theActivate == myActiveMetrics.Contains (theMetricType))
299 {
300 return;
301 }
302
303 if (theActivate)
304 {
305 myActiveMetrics.Add (theMetricType);
306 }
307 else
308 {
309 myActiveMetrics.RemoveKey (theMetricType);
310 }
311 }
312
313 //=======================================================================
314 //function : Dump
315 //purpose :
316 //=======================================================================
317
Dump(Standard_OStream & theOS)318 void Message_Report::Dump (Standard_OStream& theOS)
319 {
320 for (int iGravity = Message_Trace; iGravity <= Message_Fail; ++iGravity)
321 {
322 Dump (theOS, (Message_Gravity)iGravity);
323 }
324 }
325
326 //=======================================================================
327 //function : Dump
328 //purpose :
329 //=======================================================================
330
Dump(Standard_OStream & theOS,Message_Gravity theGravity)331 void Message_Report::Dump (Standard_OStream& theOS, Message_Gravity theGravity)
332 {
333 if (compositeAlerts().IsNull())
334 {
335 return;
336 }
337
338 if (compositeAlerts().IsNull())
339 {
340 return;
341 }
342
343 dumpMessages (theOS, theGravity, compositeAlerts());
344 }
345
346 //=======================================================================
347 //function : SendMessages
348 //purpose :
349 //=======================================================================
350
SendMessages(const Handle (Message_Messenger)& theMessenger)351 void Message_Report::SendMessages (const Handle(Message_Messenger)& theMessenger)
352 {
353 for (int aGravIter = Message_Trace; aGravIter <= Message_Fail; ++aGravIter)
354 {
355 SendMessages (theMessenger, (Message_Gravity)aGravIter);
356 }
357 }
358
359 //=======================================================================
360 //function : SendMessages
361 //purpose :
362 //=======================================================================
363
SendMessages(const Handle (Message_Messenger)& theMessenger,Message_Gravity theGravity)364 void Message_Report::SendMessages (const Handle(Message_Messenger)& theMessenger, Message_Gravity theGravity)
365 {
366 if (compositeAlerts().IsNull())
367 {
368 return;
369 }
370
371 sendMessages (theMessenger, theGravity, compositeAlerts());
372 }
373
374 //=======================================================================
375 //function : Merge
376 //purpose :
377 //=======================================================================
378
Merge(const Handle (Message_Report)& theOther)379 void Message_Report::Merge (const Handle(Message_Report)& theOther)
380 {
381 for (int aGravIter = Message_Trace; aGravIter <= Message_Fail; ++aGravIter)
382 {
383 Merge (theOther, (Message_Gravity)aGravIter);
384 }
385 }
386
387 //=======================================================================
388 //function : Merge
389 //purpose :
390 //=======================================================================
391
Merge(const Handle (Message_Report)& theOther,Message_Gravity theGravity)392 void Message_Report::Merge (const Handle(Message_Report)& theOther, Message_Gravity theGravity)
393 {
394 for (Message_ListOfAlert::Iterator anIt (theOther->GetAlerts(theGravity)); anIt.More(); anIt.Next())
395 {
396 AddAlert (theGravity, anIt.Value());
397 }
398 }
399
400 //=======================================================================
401 //function : CompositeAlerts
402 //purpose :
403 //=======================================================================
Handle(Message_CompositeAlerts)404 const Handle(Message_CompositeAlerts)& Message_Report::compositeAlerts (const Standard_Boolean isCreate)
405 {
406 if (myCompositAlerts.IsNull() && isCreate)
407 {
408 myCompositAlerts = new Message_CompositeAlerts();
409 }
410
411 return myCompositAlerts;
412 }
413
414 //=======================================================================
415 //function : sendMessages
416 //purpose :
417 //=======================================================================
sendMessages(const Handle (Message_Messenger)& theMessenger,Message_Gravity theGravity,const Handle (Message_CompositeAlerts)& theCompositeAlert)418 void Message_Report::sendMessages (const Handle(Message_Messenger)& theMessenger, Message_Gravity theGravity,
419 const Handle(Message_CompositeAlerts)& theCompositeAlert)
420 {
421 if (theCompositeAlert.IsNull())
422 {
423 return;
424 }
425
426 const Message_ListOfAlert& anAlerts = theCompositeAlert->Alerts (theGravity);
427 for (Message_ListOfAlert::Iterator anIt (anAlerts); anIt.More(); anIt.Next())
428 {
429 theMessenger->Send (anIt.Value()->GetMessageKey(), theGravity);
430 Handle(Message_AlertExtended) anExtendedAlert = Handle(Message_AlertExtended)::DownCast (anIt.Value());
431 if (anExtendedAlert.IsNull())
432 {
433 continue;
434 }
435
436 Handle(Message_CompositeAlerts) aCompositeAlerts = anExtendedAlert->CompositeAlerts();
437 if (aCompositeAlerts.IsNull())
438 {
439 continue;
440 }
441
442 sendMessages (theMessenger, theGravity, aCompositeAlerts);
443 }
444 }
445
446 //=======================================================================
447 //function : dumpMessages
448 //purpose :
449 //=======================================================================
dumpMessages(Standard_OStream & theOS,Message_Gravity theGravity,const Handle (Message_CompositeAlerts)& theCompositeAlert)450 void Message_Report::dumpMessages (Standard_OStream& theOS, Message_Gravity theGravity,
451 const Handle(Message_CompositeAlerts)& theCompositeAlert)
452 {
453 if (theCompositeAlert.IsNull())
454 {
455 return;
456 }
457
458 const Message_ListOfAlert& anAlerts = theCompositeAlert->Alerts (theGravity);
459 for (Message_ListOfAlert::Iterator anIt (anAlerts); anIt.More(); anIt.Next())
460 {
461 theOS << anIt.Value()->GetMessageKey() << std::endl;
462
463 Handle(Message_AlertExtended) anExtendedAlert = Handle(Message_AlertExtended)::DownCast (anIt.Value());
464 if (anExtendedAlert.IsNull())
465 {
466 continue;
467 }
468
469 dumpMessages (theOS, theGravity, anExtendedAlert->CompositeAlerts());
470 }
471 }
472
473 //=======================================================================
474 //function : DumpJson
475 //purpose :
476 //=======================================================================
DumpJson(Standard_OStream & theOStream,Standard_Integer theDepth) const477 void Message_Report::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
478 {
479 OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
480
481 if (!myCompositAlerts.IsNull())
482 {
483 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, myCompositAlerts.get())
484 }
485
486 Standard_Integer anAlertLevels = myAlertLevels.Size();
487 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, anAlertLevels)
488
489 Standard_Integer anInc = 1;
490 for (NCollection_IndexedMap<Message_MetricType>::Iterator anIterator (myActiveMetrics); anIterator.More(); anIterator.Next())
491 {
492 Message_MetricType anActiveMetric = anIterator.Value();
493 OCCT_DUMP_FIELD_VALUE_NUMERICAL_INC (theOStream, anActiveMetric, anInc++)
494 }
495
496 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myLimit)
497 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsActiveInMessenger)
498 }
499