b311480e |
1 | // Created on: 2003-03-04 |
2 | // Created by: Pavel TELKOV |
973c2be1 |
3 | // Copyright (c) 2003-2014 OPEN CASCADE SAS |
b311480e |
4 | // |
973c2be1 |
5 | // This file is part of Open CASCADE Technology software library. |
b311480e |
6 | // |
973c2be1 |
7 | // This library is free software; you can redistribute it and / or modify it |
8 | // under the terms of the GNU Lesser General Public 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. |
b311480e |
12 | // |
973c2be1 |
13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. |
b311480e |
15 | |
7fd59977 |
16 | // The original implementation copyright (c) RINA S.p.A. |
17 | |
18 | #include <Message_Algorithm.ixx> |
19 | |
20 | #include <Message.hxx> |
21 | #include <Message_Msg.hxx> |
22 | #include <Message_MsgFile.hxx> |
23 | #include <Message_Messenger.hxx> |
24 | #include <Standard_AncestorIterator.hxx> |
25 | #include <TCollection_AsciiString.hxx> |
26 | #include <TColStd_SequenceOfInteger.hxx> |
27 | #include <TColStd_HSequenceOfInteger.hxx> |
28 | #include <TColStd_HSequenceOfHExtendedString.hxx> |
29 | #include <TColStd_MapIteratorOfPackedMapOfInteger.hxx> |
30 | |
31 | //======================================================================= |
32 | //function : SetMessenger |
33 | //purpose : |
34 | //======================================================================= |
35 | |
36 | Message_Algorithm::Message_Algorithm () |
37 | { |
38 | myMessenger = Message::DefaultMessenger(); |
39 | } |
40 | |
41 | //======================================================================= |
42 | //function : SetMessenger |
43 | //purpose : |
44 | //======================================================================= |
45 | |
46 | void Message_Algorithm::SetMessenger (const Handle(Message_Messenger)& theMsgr) |
47 | { |
48 | if ( theMsgr.IsNull() ) |
49 | myMessenger = Message::DefaultMessenger(); |
50 | else |
51 | myMessenger = theMsgr; |
52 | } |
53 | |
54 | //======================================================================= |
55 | //function : SetStatus |
56 | //purpose : |
57 | //======================================================================= |
58 | |
59 | void Message_Algorithm::SetStatus(const Message_Status& theStat) |
60 | { |
61 | myStatus.Set( theStat ); |
62 | } |
63 | |
64 | //======================================================================= |
65 | //function : SetStatus |
66 | //purpose : |
67 | //======================================================================= |
68 | |
69 | void Message_Algorithm::SetStatus (const Message_Status& theStat, |
70 | const Standard_Integer theInt) |
71 | { |
72 | // Set status flag |
73 | SetStatus ( theStat ); |
74 | |
75 | // Find index of bit corresponding to that flag |
76 | Standard_Integer aFlagIndex = Message_ExecStatus::StatusIndex(theStat); |
77 | if ( !aFlagIndex ) return; |
78 | |
79 | // Create map of integer parameters for a given flag, if not yet done |
80 | if ( myReportIntegers.IsNull() ) |
81 | myReportIntegers = new TColStd_HArray1OfTransient (Message_ExecStatus::FirstStatus, |
82 | Message_ExecStatus::LastStatus); |
83 | Handle(Standard_Transient)& aData = |
84 | myReportIntegers->ChangeValue(aFlagIndex); |
85 | if ( aData.IsNull() ) |
86 | aData = new TColStd_HPackedMapOfInteger; |
87 | |
88 | // add integer parameter for the status |
89 | Handle(TColStd_HPackedMapOfInteger)::DownCast(aData)->ChangeMap().Add(theInt); |
90 | } |
91 | |
92 | //======================================================================= |
93 | //function : SetStatus |
94 | //purpose : |
95 | //======================================================================= |
96 | |
97 | void Message_Algorithm::SetStatus (const Message_Status& theStat, |
98 | const Handle(TCollection_HExtendedString) &theStr, |
99 | const Standard_Boolean noRepetitions) |
100 | { |
101 | // Set status flag |
102 | SetStatus ( theStat ); |
103 | if ( theStr.IsNull() ) |
104 | return; |
105 | |
106 | // Find index of bit corresponding to that flag |
107 | Standard_Integer aFlagIndex = Message_ExecStatus::StatusIndex(theStat); |
108 | if ( !aFlagIndex ) return; |
109 | |
110 | // Create sequence of string parameters for a given flag, if not yet done |
111 | if ( myReportStrings.IsNull() ) |
112 | myReportStrings = new TColStd_HArray1OfTransient (Message_ExecStatus::FirstStatus, |
113 | Message_ExecStatus::LastStatus); |
114 | Handle(Standard_Transient)& aData = |
115 | myReportStrings->ChangeValue(aFlagIndex); |
116 | if ( aData.IsNull() ) |
117 | aData = new TColStd_HSequenceOfHExtendedString; |
118 | |
119 | // Add string parameter |
120 | Handle(TColStd_HSequenceOfHExtendedString) aReportSeq = |
121 | Handle(TColStd_HSequenceOfHExtendedString)::DownCast(aData); |
122 | if ( aReportSeq.IsNull() ) |
123 | return; |
124 | if ( noRepetitions ) |
125 | { |
126 | // if the provided string has been already registered, just do nothing |
127 | for ( Standard_Integer i=1; i <= aReportSeq->Length(); i++ ) |
128 | if ( aReportSeq->Value(i)->String().IsEqual( theStr->String() ) ) |
129 | return; |
130 | } |
131 | |
132 | aReportSeq->Append ( theStr ); |
133 | } |
134 | |
15cea4ef |
135 | //======================================================================= |
136 | //function : SetStatus |
137 | //purpose : |
138 | //======================================================================= |
139 | |
140 | void Message_Algorithm::SetStatus (const Message_Status& theStat, |
141 | const Message_Msg& theMsg) |
142 | { |
143 | // Set status flag |
144 | SetStatus (theStat); |
145 | |
146 | // Find index of bit corresponding to that flag |
147 | Standard_Integer aFlagIndex = Message_ExecStatus::StatusIndex (theStat); |
148 | if (aFlagIndex == 0) |
149 | { |
150 | return; |
151 | } |
152 | |
153 | // Create sequence of messages for a given flag, if not yet done |
154 | if (myReportMessages.IsNull()) |
155 | { |
156 | myReportMessages = new Message_ArrayOfMsg (Message_ExecStatus::FirstStatus, Message_ExecStatus::LastStatus); |
157 | } |
158 | |
159 | myReportMessages->ChangeValue (aFlagIndex) = new Message_Msg (theMsg); |
160 | } |
161 | |
7fd59977 |
162 | //======================================================================= |
163 | //function : ClearStatus |
164 | //purpose : |
165 | //======================================================================= |
166 | |
15cea4ef |
167 | void Message_Algorithm::ClearStatus() |
168 | { |
7fd59977 |
169 | myStatus.Clear(); |
170 | myReportIntegers.Nullify(); |
171 | myReportStrings.Nullify(); |
15cea4ef |
172 | myReportMessages.Nullify(); |
7fd59977 |
173 | } |
174 | |
175 | //======================================================================= |
176 | //function : SendStatusMessages |
15cea4ef |
177 | //purpose : |
7fd59977 |
178 | //======================================================================= |
179 | |
180 | void Message_Algorithm::SendStatusMessages (const Message_ExecStatus& theStatus, |
15cea4ef |
181 | const Message_Gravity theTraceLevel, |
182 | const Standard_Integer theMaxCount) const |
7fd59977 |
183 | { |
184 | Handle(Message_Messenger) aMsgr = GetMessenger(); |
15cea4ef |
185 | if (aMsgr.IsNull()) |
186 | { |
187 | return; |
188 | } |
7fd59977 |
189 | |
15cea4ef |
190 | const TCollection_AsciiString aClassName (DynamicType()->Name()); |
7fd59977 |
191 | |
192 | // Iterate on all set flags in the specified range |
193 | for ( Standard_Integer i = Message_ExecStatus::FirstStatus; |
194 | i <= Message_ExecStatus::LastStatus; i++ ) |
195 | { |
196 | Message_Status stat = Message_ExecStatus::StatusByIndex( i ); |
15cea4ef |
197 | if (!theStatus.IsSet (stat) || !myStatus.IsSet (stat)) |
198 | { |
7fd59977 |
199 | continue; |
15cea4ef |
200 | } |
201 | |
202 | Handle(Message_Msg) aMsgCustom = !myReportMessages.IsNull() |
203 | ? myReportMessages->Value (i) |
204 | : Handle(Message_Msg)(); |
205 | if (!aMsgCustom.IsNull()) |
206 | { |
207 | // print custom message |
208 | aMsgr->Send (*aMsgCustom, theTraceLevel); |
209 | continue; |
210 | } |
7fd59977 |
211 | |
212 | // construct message suffix |
213 | TCollection_AsciiString aSuffix; |
214 | switch( Message_ExecStatus::TypeOfStatus( stat ) ) |
215 | { |
216 | case Message_DONE: aSuffix.AssignCat( ".Done" ); break; |
217 | case Message_WARN: aSuffix.AssignCat( ".Warn" ); break; |
218 | case Message_ALARM: aSuffix.AssignCat( ".Alarm"); break; |
219 | case Message_FAIL: aSuffix.AssignCat( ".Fail" ); break; |
220 | default: continue; |
221 | } |
222 | aSuffix.AssignCat( Message_ExecStatus::LocalStatusIndex( stat ) ); |
223 | |
224 | // find message, iterating by base classes if necessary |
225 | TCollection_AsciiString aMsgName = aClassName + aSuffix; |
226 | Handle(Standard_Type) aType = DynamicType(); |
227 | while (Message_MsgFile::Msg(aMsgName).Length() == 0 && !aType.IsNull()) |
228 | { |
229 | Standard_AncestorIterator it(aType); |
230 | aType.Nullify(); |
231 | for (; it.More(); it.Next()) |
232 | { |
233 | aType = it.Value(); |
234 | TCollection_AsciiString aClassName1 (aType->Name()); |
235 | TCollection_AsciiString aMsgName1 = aClassName1 + aSuffix; |
236 | if (Message_MsgFile::Msg(aMsgName1).Length() != 0) |
237 | { |
238 | aMsgName = aMsgName1; |
239 | break; |
240 | } |
241 | } |
242 | } |
243 | |
244 | // create a message |
245 | Message_Msg aMsg ( aMsgName ); |
246 | |
247 | // if additional parameters are defined for a given status flag, |
248 | // try to feed them into the message |
15cea4ef |
249 | if (!myReportIntegers.IsNull()) |
7fd59977 |
250 | { |
251 | Handle(TColStd_HPackedMapOfInteger) aMapErrors = |
15cea4ef |
252 | Handle(TColStd_HPackedMapOfInteger)::DownCast(myReportIntegers->Value(i)); |
253 | if (!aMapErrors.IsNull()) |
254 | { |
255 | aMsg << PrepareReport (aMapErrors, theMaxCount); |
256 | } |
7fd59977 |
257 | } |
15cea4ef |
258 | if (!myReportStrings.IsNull() |
259 | && !myReportStrings->Value (i).IsNull()) |
7fd59977 |
260 | { |
15cea4ef |
261 | Handle(TColStd_HSequenceOfHExtendedString) aReportSeq = |
262 | Handle(TColStd_HSequenceOfHExtendedString)::DownCast (myReportStrings->Value(i)); |
263 | if (!aReportSeq.IsNull()) |
264 | { |
265 | aMsg << PrepareReport (aReportSeq->Sequence(), theMaxCount); |
266 | } |
7fd59977 |
267 | } |
268 | |
269 | // output the message |
270 | aMsgr->Send(aMsg, theTraceLevel); |
271 | } |
272 | } |
273 | |
274 | //======================================================================= |
275 | //function : SendMessages |
276 | //purpose : |
277 | //======================================================================= |
278 | |
279 | void Message_Algorithm::SendMessages (const Message_Gravity theTraceLevel, |
280 | const Standard_Integer theMaxCount) const |
281 | { |
282 | Message_ExecStatus aStat; |
283 | aStat.SetAllWarn(); |
284 | aStat.SetAllAlarm(); |
285 | aStat.SetAllFail(); |
286 | SendStatusMessages( aStat, theTraceLevel, theMaxCount ); |
287 | } |
288 | |
289 | //======================================================================= |
290 | //function : AddStatus |
291 | //purpose : |
292 | //======================================================================= |
293 | |
294 | void Message_Algorithm::AddStatus |
295 | (const Handle(Message_Algorithm)& theOtherAlgo) |
296 | { |
297 | AddStatus( theOtherAlgo->GetStatus(), theOtherAlgo ); |
298 | } |
299 | |
300 | //======================================================================= |
301 | //function : AddStatus |
302 | //purpose : |
303 | //======================================================================= |
304 | |
305 | void Message_Algorithm::AddStatus |
306 | (const Message_ExecStatus& theAllowedStatus, |
307 | const Handle(Message_Algorithm)& theOtherAlgo) |
308 | { |
309 | // Iterate on all set flags in the specified range |
310 | const Message_ExecStatus& aStatusOfAlgo = theOtherAlgo->GetStatus(); |
311 | for ( Standard_Integer i = Message_ExecStatus::FirstStatus; |
312 | i <= Message_ExecStatus::LastStatus; i++ ) |
313 | { |
314 | Message_Status stat = Message_ExecStatus::StatusByIndex( i ); |
315 | if ( ! theAllowedStatus.IsSet( stat ) || ! aStatusOfAlgo.IsSet( stat ) ) |
316 | continue; |
317 | |
318 | SetStatus ( stat ); |
319 | |
320 | // if additional parameters are defined for a given status flag, |
321 | // move them to <this> algorithm |
322 | // a) numbers |
323 | Handle(TColStd_HPackedMapOfInteger) aNumsOther = |
324 | theOtherAlgo->GetMessageNumbers (stat); |
325 | if ( ! aNumsOther.IsNull() ) |
326 | { |
327 | // Create sequence of integer parameters for a given flag, if not yet done |
328 | if ( myReportIntegers.IsNull() ) |
329 | myReportIntegers = |
330 | new TColStd_HArray1OfTransient(Message_ExecStatus::FirstStatus, |
331 | Message_ExecStatus::LastStatus); |
332 | Handle(Standard_Transient)& aData = |
333 | myReportIntegers->ChangeValue(i); |
334 | if ( aData.IsNull() ) |
335 | aData = new TColStd_HPackedMapOfInteger; |
336 | |
337 | // add integer parameter for the status |
338 | Handle(TColStd_HPackedMapOfInteger)::DownCast(aData) |
339 | ->ChangeMap().Unite(aNumsOther->Map()); |
340 | } |
341 | // b) strings |
342 | Handle(TColStd_HSequenceOfHExtendedString) aStrsOther = |
343 | theOtherAlgo->GetMessageStrings (stat); |
344 | if ( ! aStrsOther.IsNull() ) |
345 | { |
346 | for (Standard_Integer n=1; n < aStrsOther->Length(); n++ ) |
347 | SetStatus (stat, aStrsOther->Value(n)); |
348 | } |
349 | } |
350 | } |
351 | |
352 | //======================================================================= |
353 | //function : GetMessageNumbers |
354 | //purpose : |
355 | //======================================================================= |
356 | |
357 | Handle(TColStd_HPackedMapOfInteger) Message_Algorithm::GetMessageNumbers |
358 | (const Message_Status& theStatus) const |
359 | { |
360 | if ( myReportIntegers.IsNull() ) |
361 | return 0; |
362 | |
363 | // Find index of bit corresponding to that flag |
364 | Standard_Integer aFlagIndex = Message_ExecStatus::StatusIndex(theStatus); |
365 | if ( ! aFlagIndex ) return 0; |
366 | |
367 | return Handle(TColStd_HPackedMapOfInteger)::DownCast(myReportIntegers->Value(aFlagIndex)); |
368 | } |
369 | |
370 | //======================================================================= |
371 | //function : GetMessageStrings |
372 | //purpose : |
373 | //======================================================================= |
374 | |
375 | Handle(TColStd_HSequenceOfHExtendedString) Message_Algorithm::GetMessageStrings |
376 | (const Message_Status& theStatus) const |
377 | { |
378 | if ( myReportStrings.IsNull() ) |
379 | return 0; |
380 | |
381 | // Find index of bit corresponding to that flag |
382 | Standard_Integer aFlagIndex = Message_ExecStatus::StatusIndex(theStatus); |
383 | if ( ! aFlagIndex ) return 0; |
384 | |
385 | return Handle(TColStd_HSequenceOfHExtendedString)::DownCast(myReportStrings->Value(aFlagIndex)); |
386 | } |
387 | |
388 | //======================================================================= |
389 | //function : PrepareReport |
390 | //purpose : static method |
391 | //======================================================================= |
392 | |
393 | TCollection_ExtendedString Message_Algorithm::PrepareReport |
394 | (const Handle(TColStd_HPackedMapOfInteger)& theMapError, |
395 | const Standard_Integer theMaxCount) |
396 | { |
397 | TCollection_ExtendedString aNewReport; |
398 | TColStd_MapIteratorOfPackedMapOfInteger anIt(theMapError->Map()); |
399 | Standard_Integer nb = 1; |
400 | for (; anIt.More() && nb <= theMaxCount; anIt.Next(), nb++ ) |
401 | { |
402 | if ( nb > 1 ) |
403 | aNewReport += " "; |
404 | aNewReport += anIt.Key(); |
405 | } |
406 | |
407 | if ( anIt.More() ) |
408 | { |
409 | aNewReport += " ... (total "; |
410 | aNewReport += theMapError->Map().Extent(); |
411 | aNewReport += ")"; |
412 | } |
413 | return aNewReport; |
414 | } |
415 | |
416 | //======================================================================= |
417 | //function : PrepareReport |
418 | //purpose : static method |
419 | //======================================================================= |
420 | |
421 | TCollection_ExtendedString Message_Algorithm::PrepareReport |
422 | (const TColStd_SequenceOfHExtendedString& theReportSeq, |
423 | const Standard_Integer theMaxCount) |
424 | { |
425 | TCollection_ExtendedString aNewReport; |
426 | Standard_Integer nb = 1; |
427 | for ( ; nb <= theReportSeq.Length() && nb <= theMaxCount; nb++) |
428 | { |
429 | aNewReport += (Standard_CString)( nb > 1 ? ", \'" : "\'" ); |
430 | aNewReport += theReportSeq.Value(nb)->String(); |
431 | aNewReport += "\'"; |
432 | } |
433 | |
434 | if (theReportSeq.Length() > theMaxCount ) |
435 | { |
436 | aNewReport += " ... (total "; |
437 | aNewReport += theReportSeq.Length(); |
438 | aNewReport += ") "; |
439 | } |
440 | return aNewReport; |
441 | } |