1 // Created on: 2017-06-26
2 // Created by: Andrey Betenev
3 // Copyright (c) 2017 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <Message_Report.hxx>
17 #include <Message_Msg.hxx>
18 #include <Message_Messenger.hxx>
19 #include <NCollection_Map.hxx>
21 IMPLEMENT_STANDARD_RTTIEXT(Message_Report,Standard_Transient)
23 //=======================================================================
24 //function : Message_Report
26 //=======================================================================
28 Message_Report::Message_Report ()
32 //=======================================================================
35 //=======================================================================
37 void Message_Report::AddAlert (Message_Gravity theGravity, const Handle(Message_Alert)& theAlert)
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",);
43 Standard_Mutex::Sentry aSentry (myMutex);
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())
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())
53 // if merged successfully, just return
54 if (aType == anIt.Value()->DynamicType() && theAlert->Merge (anIt.Value()))
59 // if not merged, just add to the list
60 aList.Append (theAlert);
63 //=======================================================================
64 //function : GetAlerts
66 //=======================================================================
68 const Message_ListOfAlert& Message_Report::GetAlerts (Message_Gravity theGravity) const
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];
76 //=======================================================================
79 //=======================================================================
81 Standard_Boolean Message_Report::HasAlert (const Handle(Standard_Type)& theType)
83 for (int iGravity = Message_Trace; iGravity <= Message_Fail; ++iGravity)
85 if (HasAlert (theType, (Message_Gravity)iGravity))
88 return Standard_False;
91 //=======================================================================
94 //=======================================================================
96 Standard_Boolean Message_Report::HasAlert (const Handle(Standard_Type)& theType, Message_Gravity theGravity)
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())
102 if (anIt.Value()->IsInstance(theType))
103 return Standard_True;
105 return Standard_False;
108 //=======================================================================
111 //=======================================================================
113 void Message_Report::Clear ()
115 for (unsigned int i = 0; i < sizeof(myAlerts)/sizeof(myAlerts[0]); ++i)
121 //=======================================================================
124 //=======================================================================
126 void Message_Report::Clear (Message_Gravity theGravity)
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();
133 //=======================================================================
136 //=======================================================================
138 void Message_Report::Clear (const Handle(Standard_Type)& theType)
140 for (unsigned int i = 0; i < sizeof(myAlerts)/sizeof(myAlerts[0]); ++i)
142 for (Message_ListOfAlert::Iterator anIt (myAlerts[i]); anIt.More(); )
144 if (anIt.Value().IsNull() || anIt.Value()->IsInstance (theType))
146 myAlerts[i].Remove (anIt);
156 //=======================================================================
159 //=======================================================================
161 void Message_Report::Dump (Standard_OStream& theOS)
163 for (int iGravity = Message_Trace; iGravity <= Message_Fail; ++iGravity)
165 Dump (theOS, (Message_Gravity)iGravity);
169 //=======================================================================
172 //=======================================================================
174 void Message_Report::Dump (Standard_OStream& theOS, Message_Gravity theGravity)
176 Standard_ASSERT_RETURN (theGravity >= 0 && size_t(theGravity) < sizeof(myAlerts)/sizeof(myAlerts[0]),
177 "Requesting alerts for gravity not in valid range", );
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())
183 if (aPassedAlerts.Add (anIt.Value()->DynamicType()))
185 Message_Msg aMsg (anIt.Value()->GetMessageKey());
186 theOS << aMsg.Original() << std::endl;
191 //=======================================================================
192 //function : SendMessages
194 //=======================================================================
196 void Message_Report::SendMessages (const Handle(Message_Messenger)& theMessenger)
198 for (int iGravity = Message_Trace; iGravity <= Message_Fail; ++iGravity)
200 SendMessages (theMessenger, (Message_Gravity)iGravity);
204 //=======================================================================
205 //function : SendMessages
207 //=======================================================================
209 void Message_Report::SendMessages (const Handle(Message_Messenger)& theMessenger, Message_Gravity theGravity)
211 Standard_ASSERT_RETURN (theGravity >= 0 && size_t(theGravity) < sizeof(myAlerts)/sizeof(myAlerts[0]),
212 "Requesting alerts for gravity not in valid range", );
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())
218 if (aPassedAlerts.Add (anIt.Value()->DynamicType()))
220 Message_Msg aMsg (anIt.Value()->GetMessageKey());
221 theMessenger->Send (aMsg, theGravity);
226 //=======================================================================
229 //=======================================================================
231 void Message_Report::Merge (const Handle(Message_Report)& theOther)
233 for (int iGravity = Message_Trace; iGravity <= Message_Fail; ++iGravity)
235 Merge (theOther, (Message_Gravity)iGravity);
239 //=======================================================================
242 //=======================================================================
244 void Message_Report::Merge (const Handle(Message_Report)& theOther, Message_Gravity theGravity)
246 for (Message_ListOfAlert::Iterator anIt (theOther->GetAlerts(theGravity)); anIt.More(); anIt.Next())
248 AddAlert (theGravity, anIt.Value());