07324599d2fc5bbed00fe24b37848cd2221143b9
[occt.git] / src / Message / Message_Report.cxx
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 #include <Message_Msg.hxx>
18 #include <Message_Messenger.hxx>
19 #include <NCollection_Map.hxx>
20
21 IMPLEMENT_STANDARD_RTTIEXT(Message_Report,Standard_Transient)
22
23 //=======================================================================
24 //function : Message_Report
25 //purpose  :
26 //=======================================================================
27
28 Message_Report::Message_Report ()
29 {
30 }
31
32 //=======================================================================
33 //function : AddAlert
34 //purpose  :
35 //=======================================================================
36
37 void Message_Report::AddAlert (Message_Gravity theGravity, const Handle(Message_Alert)& theAlert)
38 {
39   Standard_ASSERT_RETURN (! theAlert.IsNull(), "Attempt to add null alert",);
40   Standard_ASSERT_RETURN (theGravity >= 0 && size_t(theGravity) < sizeof(myAlerts)/sizeof(myAlerts[0]), 
41                           "Adding alert with gravity not in valid range",);
42
43   Standard_Mutex::Sentry aSentry (myMutex);
44
45   // iterate by already recorded alerts and try to merge new one with one of those
46   Message_ListOfAlert &aList = myAlerts[theGravity];
47   if (theAlert->SupportsMerge() && ! aList.IsEmpty())
48   {
49     // merge is performed only for alerts of exactly same type
50     const Handle(Standard_Type)& aType = theAlert->DynamicType();
51     for (Message_ListOfAlert::Iterator anIt(aList); anIt.More(); anIt.Next())
52     {
53       // if merged successfully, just return
54       if (aType == anIt.Value()->DynamicType() && theAlert->Merge (anIt.Value()))
55         return;
56     }
57   }
58
59   // if not merged, just add to the list
60   aList.Append (theAlert);
61 }
62
63 //=======================================================================
64 //function : GetAlerts
65 //purpose  :
66 //=======================================================================
67
68 const Message_ListOfAlert& Message_Report::GetAlerts (Message_Gravity theGravity) const
69 {
70   static const Message_ListOfAlert anEmptyList;
71   Standard_ASSERT_RETURN (theGravity >= 0 && size_t(theGravity) < sizeof(myAlerts)/sizeof(myAlerts[0]), 
72                           "Requesting alerts for gravity not in valid range", anEmptyList);
73   return myAlerts[theGravity];
74 }
75
76 //=======================================================================
77 //function : HasAlert
78 //purpose  :
79 //=======================================================================
80
81 Standard_Boolean Message_Report::HasAlert (const Handle(Standard_Type)& theType)
82 {
83   for (int iGravity = Message_Trace; iGravity <= Message_Fail; ++iGravity)
84   {
85     if (HasAlert (theType, (Message_Gravity)iGravity))
86       return Standard_True;
87   }
88   return Standard_False;
89 }
90
91 //=======================================================================
92 //function : HasAlert
93 //purpose  :
94 //=======================================================================
95
96 Standard_Boolean Message_Report::HasAlert (const Handle(Standard_Type)& theType, Message_Gravity theGravity)
97 {
98   Standard_ASSERT_RETURN (theGravity >= 0 && size_t(theGravity) < sizeof(myAlerts)/sizeof(myAlerts[0]), 
99                           "Requesting alerts for gravity not in valid range", Standard_False);
100   for (Message_ListOfAlert::Iterator anIt (myAlerts[theGravity]); anIt.More(); anIt.Next())
101   {
102     if (anIt.Value()->IsInstance(theType))
103       return Standard_True;
104   }
105   return Standard_False;
106 }
107
108 //=======================================================================
109 //function : Clear
110 //purpose  :
111 //=======================================================================
112
113 void Message_Report::Clear ()
114 {
115   for (unsigned int i = 0; i < sizeof(myAlerts)/sizeof(myAlerts[0]); ++i)
116   {
117     myAlerts[i].Clear();
118   }
119 }
120
121 //=======================================================================
122 //function : Clear
123 //purpose  :
124 //=======================================================================
125
126 void Message_Report::Clear (Message_Gravity theGravity)
127 {
128   Standard_ASSERT_RETURN (theGravity >= 0 && size_t(theGravity) < sizeof(myAlerts)/sizeof(myAlerts[0]), 
129                           "Requesting alerts for gravity not in valid range", );
130   myAlerts[theGravity].Clear();
131 }
132
133 //=======================================================================
134 //function : Clear
135 //purpose  :
136 //=======================================================================
137
138 void Message_Report::Clear (const Handle(Standard_Type)& theType)
139 {
140   for (unsigned int i = 0; i < sizeof(myAlerts)/sizeof(myAlerts[0]); ++i)
141   {
142     for (Message_ListOfAlert::Iterator anIt (myAlerts[i]); anIt.More(); )
143     {
144       if (anIt.Value().IsNull() || anIt.Value()->IsInstance (theType))
145       {
146         myAlerts[i].Remove (anIt);
147       }
148       else
149       {
150         anIt.More();
151       }
152     }
153   }
154 }
155
156 //=======================================================================
157 //function : Dump
158 //purpose  :
159 //=======================================================================
160
161 void Message_Report::Dump (Standard_OStream& theOS)
162 {
163   for (int iGravity = Message_Trace; iGravity <= Message_Fail; ++iGravity)
164   {
165     Dump (theOS, (Message_Gravity)iGravity);
166   }
167 }
168
169 //=======================================================================
170 //function : Dump
171 //purpose  :
172 //=======================================================================
173
174 void Message_Report::Dump (Standard_OStream& theOS, Message_Gravity theGravity)
175 {
176   Standard_ASSERT_RETURN (theGravity >= 0 && size_t(theGravity) < sizeof(myAlerts)/sizeof(myAlerts[0]), 
177                           "Requesting alerts for gravity not in valid range", );
178
179   // report each type of warning only once
180   NCollection_Map<Handle(Standard_Type)> aPassedAlerts;
181   for (Message_ListOfAlert::Iterator anIt (myAlerts[theGravity]); anIt.More(); anIt.Next())
182   {
183     if (aPassedAlerts.Add (anIt.Value()->DynamicType()))
184     {
185       Message_Msg aMsg (anIt.Value()->GetMessageKey());
186       theOS << aMsg.Original() << std::endl;
187     }
188   }
189 }
190
191 //=======================================================================
192 //function : Dump
193 //purpose  :
194 //=======================================================================
195
196 void Message_Report::SendMessages (const Handle(Message_Messenger)& theMessenger)
197 {
198   for (int iGravity = Message_Trace; iGravity <= Message_Fail; ++iGravity)
199   {
200     SendMessages (theMessenger, (Message_Gravity)iGravity);
201   }
202 }
203
204 //=======================================================================
205 //function : Dump
206 //purpose  :
207 //=======================================================================
208
209 void Message_Report::SendMessages (const Handle(Message_Messenger)& theMessenger, Message_Gravity theGravity)
210 {
211   Standard_ASSERT_RETURN (theGravity >= 0 && size_t(theGravity) < sizeof(myAlerts)/sizeof(myAlerts[0]), 
212                           "Requesting alerts for gravity not in valid range", );
213
214   // report each type of warning only once
215   NCollection_Map<Handle(Standard_Type)> aPassedAlerts;
216   for (Message_ListOfAlert::Iterator anIt (myAlerts[theGravity]); anIt.More(); anIt.Next())
217   {
218     if (aPassedAlerts.Add (anIt.Value()->DynamicType()))
219     {
220       Message_Msg aMsg (anIt.Value()->GetMessageKey());
221       theMessenger->Send (aMsg, theGravity);
222     }
223   }
224 }
225
226 //=======================================================================
227 //function : Merge
228 //purpose  :
229 //=======================================================================
230
231 void Message_Report::Merge (const Handle(Message_Report)& theOther)
232 {
233   for (int iGravity = Message_Trace; iGravity <= Message_Fail; ++iGravity)
234   {
235     Merge (theOther, (Message_Gravity)iGravity);
236   }
237 }
238
239 //=======================================================================
240 //function : Merge
241 //purpose  :
242 //=======================================================================
243
244 void Message_Report::Merge (const Handle(Message_Report)& theOther, Message_Gravity theGravity)
245 {
246   for (Message_ListOfAlert::Iterator anIt (theOther->GetAlerts(theGravity)); anIt.More(); anIt.Next())
247   {
248     AddAlert (theGravity, anIt.Value());
249   }
250 }